Avoid UB when reading Wii volume names

This commit is contained in:
JosJuice 2017-11-02 21:05:37 +01:00
parent 6902bbb696
commit 1dc2a85ccc
4 changed files with 15 additions and 16 deletions

View file

@ -26,17 +26,15 @@ namespace DiscIO
const IOS::ES::TicketReader Volume::INVALID_TICKET{}; const IOS::ES::TicketReader Volume::INVALID_TICKET{};
const IOS::ES::TMDReader Volume::INVALID_TMD{}; const IOS::ES::TMDReader Volume::INVALID_TMD{};
std::map<Language, std::string> Volume::ReadWiiNames(const std::vector<u8>& data) std::map<Language, std::string> Volume::ReadWiiNames(const std::vector<char16_t>& data)
{ {
std::map<Language, std::string> names; std::map<Language, std::string> names;
for (size_t i = 0; i < NUMBER_OF_LANGUAGES; ++i) for (size_t i = 0; i < NUMBER_OF_LANGUAGES; ++i)
{ {
size_t name_start = NAME_BYTES_LENGTH * i; const size_t name_start = NAME_CHARS_LENGTH * i;
size_t name_end = name_start + NAME_BYTES_LENGTH; if (name_start + NAME_CHARS_LENGTH <= data.size())
if (data.size() >= name_end)
{ {
std::string name = UTF16BEToUTF8(reinterpret_cast<const char16_t*>(data.data() + name_start), const std::string name = UTF16BEToUTF8(data.data() + name_start, NAME_CHARS_LENGTH);
NAME_STRING_LENGTH);
if (!name.empty()) if (!name.empty())
names[static_cast<Language>(i)] = name; names[static_cast<Language>(i)] = name;
} }

View file

@ -116,11 +116,12 @@ protected:
} }
virtual u32 GetOffsetShift() const { return 0; } virtual u32 GetOffsetShift() const { return 0; }
static std::map<Language, std::string> ReadWiiNames(const std::vector<u8>& data); static std::map<Language, std::string> ReadWiiNames(const std::vector<char16_t>& data);
static const size_t NUMBER_OF_LANGUAGES = 10; static const size_t NUMBER_OF_LANGUAGES = 10;
static const size_t NAME_STRING_LENGTH = 42; static const size_t NAME_CHARS_LENGTH = 42;
static const size_t NAME_BYTES_LENGTH = NAME_STRING_LENGTH * sizeof(u16); static const size_t NAME_BYTES_LENGTH = NAME_CHARS_LENGTH * sizeof(char16_t);
static const size_t NAMES_TOTAL_CHARS = NAME_CHARS_LENGTH * NUMBER_OF_LANGUAGES;
static const size_t NAMES_TOTAL_BYTES = NAME_BYTES_LENGTH * NUMBER_OF_LANGUAGES; static const size_t NAMES_TOTAL_BYTES = NAME_BYTES_LENGTH * NUMBER_OF_LANGUAGES;
static const IOS::ES::TicketReader INVALID_TICKET; static const IOS::ES::TicketReader INVALID_TICKET;

View file

@ -138,10 +138,10 @@ std::map<Language, std::string> VolumeWAD::GetLongNames() const
if (!m_tmd.IsValid() || !IOS::ES::IsChannel(m_tmd.GetTitleId())) if (!m_tmd.IsValid() || !IOS::ES::IsChannel(m_tmd.GetTitleId()))
return {}; return {};
std::vector<u8> name_data(NAMES_TOTAL_BYTES); std::vector<char16_t> names(NAMES_TOTAL_CHARS);
if (!Read(m_opening_bnr_offset + 0x9C, NAMES_TOTAL_BYTES, name_data.data())) if (!Read(m_opening_bnr_offset + 0x9C, NAMES_TOTAL_BYTES, reinterpret_cast<u8*>(names.data())))
return std::map<Language, std::string>(); return std::map<Language, std::string>();
return ReadWiiNames(name_data); return ReadWiiNames(names);
} }
std::vector<u32> VolumeWAD::GetBanner(int* width, int* height) const std::vector<u32> VolumeWAD::GetBanner(int* width, int* height) const

View file

@ -302,10 +302,10 @@ std::string VolumeWii::GetInternalName(const Partition& partition) const
std::map<Language, std::string> VolumeWii::GetLongNames() const std::map<Language, std::string> VolumeWii::GetLongNames() const
{ {
std::vector<u8> opening_bnr(NAMES_TOTAL_BYTES); std::vector<char16_t> names(NAMES_TOTAL_CHARS);
opening_bnr.resize(ReadFile(*this, GetGamePartition(), "opening.bnr", opening_bnr.data(), names.resize(ReadFile(*this, GetGamePartition(), "opening.bnr",
opening_bnr.size(), 0x5C)); reinterpret_cast<u8*>(names.data()), NAMES_TOTAL_BYTES, 0x5C));
return ReadWiiNames(opening_bnr); return ReadWiiNames(names);
} }
std::vector<u32> VolumeWii::GetBanner(int* width, int* height) const std::vector<u32> VolumeWii::GetBanner(int* width, int* height) const