From 1dc2a85ccc2e3a23b9cd33d1503038223bfae320 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Thu, 2 Nov 2017 21:05:37 +0100 Subject: [PATCH] Avoid UB when reading Wii volume names --- Source/Core/DiscIO/Volume.cpp | 10 ++++------ Source/Core/DiscIO/Volume.h | 7 ++++--- Source/Core/DiscIO/VolumeWad.cpp | 6 +++--- Source/Core/DiscIO/VolumeWii.cpp | 8 ++++---- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/Source/Core/DiscIO/Volume.cpp b/Source/Core/DiscIO/Volume.cpp index 9ae87466e2..e95a2b746f 100644 --- a/Source/Core/DiscIO/Volume.cpp +++ b/Source/Core/DiscIO/Volume.cpp @@ -26,17 +26,15 @@ namespace DiscIO const IOS::ES::TicketReader Volume::INVALID_TICKET{}; const IOS::ES::TMDReader Volume::INVALID_TMD{}; -std::map Volume::ReadWiiNames(const std::vector& data) +std::map Volume::ReadWiiNames(const std::vector& data) { std::map names; for (size_t i = 0; i < NUMBER_OF_LANGUAGES; ++i) { - size_t name_start = NAME_BYTES_LENGTH * i; - size_t name_end = name_start + NAME_BYTES_LENGTH; - if (data.size() >= name_end) + const size_t name_start = NAME_CHARS_LENGTH * i; + if (name_start + NAME_CHARS_LENGTH <= data.size()) { - std::string name = UTF16BEToUTF8(reinterpret_cast(data.data() + name_start), - NAME_STRING_LENGTH); + const std::string name = UTF16BEToUTF8(data.data() + name_start, NAME_CHARS_LENGTH); if (!name.empty()) names[static_cast(i)] = name; } diff --git a/Source/Core/DiscIO/Volume.h b/Source/Core/DiscIO/Volume.h index 67609ddabe..f7172db6cc 100644 --- a/Source/Core/DiscIO/Volume.h +++ b/Source/Core/DiscIO/Volume.h @@ -116,11 +116,12 @@ protected: } virtual u32 GetOffsetShift() const { return 0; } - static std::map ReadWiiNames(const std::vector& data); + static std::map ReadWiiNames(const std::vector& data); static const size_t NUMBER_OF_LANGUAGES = 10; - static const size_t NAME_STRING_LENGTH = 42; - static const size_t NAME_BYTES_LENGTH = NAME_STRING_LENGTH * sizeof(u16); + static const size_t NAME_CHARS_LENGTH = 42; + 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 IOS::ES::TicketReader INVALID_TICKET; diff --git a/Source/Core/DiscIO/VolumeWad.cpp b/Source/Core/DiscIO/VolumeWad.cpp index d09baf1f6a..2d98986f81 100644 --- a/Source/Core/DiscIO/VolumeWad.cpp +++ b/Source/Core/DiscIO/VolumeWad.cpp @@ -138,10 +138,10 @@ std::map VolumeWAD::GetLongNames() const if (!m_tmd.IsValid() || !IOS::ES::IsChannel(m_tmd.GetTitleId())) return {}; - std::vector name_data(NAMES_TOTAL_BYTES); - if (!Read(m_opening_bnr_offset + 0x9C, NAMES_TOTAL_BYTES, name_data.data())) + std::vector names(NAMES_TOTAL_CHARS); + if (!Read(m_opening_bnr_offset + 0x9C, NAMES_TOTAL_BYTES, reinterpret_cast(names.data()))) return std::map(); - return ReadWiiNames(name_data); + return ReadWiiNames(names); } std::vector VolumeWAD::GetBanner(int* width, int* height) const diff --git a/Source/Core/DiscIO/VolumeWii.cpp b/Source/Core/DiscIO/VolumeWii.cpp index 2158e71f1a..bc0c410c13 100644 --- a/Source/Core/DiscIO/VolumeWii.cpp +++ b/Source/Core/DiscIO/VolumeWii.cpp @@ -302,10 +302,10 @@ std::string VolumeWii::GetInternalName(const Partition& partition) const std::map VolumeWii::GetLongNames() const { - std::vector opening_bnr(NAMES_TOTAL_BYTES); - opening_bnr.resize(ReadFile(*this, GetGamePartition(), "opening.bnr", opening_bnr.data(), - opening_bnr.size(), 0x5C)); - return ReadWiiNames(opening_bnr); + std::vector names(NAMES_TOTAL_CHARS); + names.resize(ReadFile(*this, GetGamePartition(), "opening.bnr", + reinterpret_cast(names.data()), NAMES_TOTAL_BYTES, 0x5C)); + return ReadWiiNames(names); } std::vector VolumeWii::GetBanner(int* width, int* height) const