WIA: Properly check for overlapping data

This commit is contained in:
JosJuice 2020-01-27 14:26:12 +01:00
parent 04089f24f9
commit 47067f661a
2 changed files with 40 additions and 4 deletions

View File

@ -142,10 +142,7 @@ bool WIAFileReader::Initialize(const std::string& path)
if (non_empty_entries > 1) if (non_empty_entries > 1)
{ {
const u32 first_end = if (Common::swap32(entries[0].first_sector) > Common::swap32(entries[1].first_sector))
Common::swap32(entries[0].first_sector) + Common::swap32(entries[0].number_of_sectors);
const u32 second_start = Common::swap32(entries[1].first_sector);
if (first_end > second_start)
return false; return false;
} }
} }
@ -175,9 +172,47 @@ bool WIAFileReader::Initialize(const std::string& path)
if (!group_entries.ReadAll(&m_group_entries)) if (!group_entries.ReadAll(&m_group_entries))
return false; return false;
if (HasDataOverlap())
return false;
return true; return true;
} }
bool WIAFileReader::HasDataOverlap() const
{
for (size_t i = 0; i < m_partition_entries.size(); ++i)
{
const std::array<PartitionDataEntry, 2>& entries = m_partition_entries[i].data_entries;
for (size_t j = 0; j < entries.size(); ++j)
{
if (Common::swap32(entries[j].number_of_sectors) == 0)
continue;
const u64 data_offset = Common::swap32(entries[j].first_sector) * VolumeWii::BLOCK_TOTAL_SIZE;
const auto it = m_data_entries.upper_bound(data_offset);
if (it == m_data_entries.end())
return true; // Not an overlap, but an error nonetheless
if (!it->second.is_partition || it->second.index != i || it->second.partition_data_index != j)
return true; // Overlap
}
}
for (size_t i = 0; i < m_raw_data_entries.size(); ++i)
{
if (Common::swap64(m_raw_data_entries[i].data_size) == 0)
continue;
const u64 data_offset = Common::swap64(m_raw_data_entries[i].data_offset);
const auto it = m_data_entries.upper_bound(data_offset);
if (it == m_data_entries.end())
return true; // Not an overlap, but an error nonetheless
if (it->second.is_partition || it->second.index != i)
return true; // Overlap
}
return false;
}
std::unique_ptr<WIAFileReader> WIAFileReader::Create(File::IOFile file, const std::string& path) std::unique_ptr<WIAFileReader> WIAFileReader::Create(File::IOFile file, const std::string& path)
{ {
std::unique_ptr<WIAFileReader> blob(new WIAFileReader(std::move(file), path)); std::unique_ptr<WIAFileReader> blob(new WIAFileReader(std::move(file), path));

View File

@ -261,6 +261,7 @@ private:
explicit WIAFileReader(File::IOFile file, const std::string& path); explicit WIAFileReader(File::IOFile file, const std::string& path);
bool Initialize(const std::string& path); bool Initialize(const std::string& path);
bool HasDataOverlap() const;
bool ReadFromGroups(u64* offset, u64* size, u8** out_ptr, u64 chunk_size, u32 sector_size, bool ReadFromGroups(u64* offset, u64* size, u8** out_ptr, u64 chunk_size, u32 sector_size,
u64 data_offset, u64 data_size, u32 group_index, u32 number_of_groups, u64 data_offset, u64 data_size, u32 group_index, u32 number_of_groups,