DiscIO: Fix reading certain WIA chunks with many exceptions
The loop in WIARVZFileReader::Chunk::Read could terminate prematurely if the size argument was smaller than the size of an exception list which had only been partially loaded.
This commit is contained in:
parent
de30559862
commit
14bfc0be78
|
@ -653,7 +653,7 @@ bool WIARVZFileReader<RVZ>::Chunk::Read(u64 offset, u64 size, u8* out_ptr)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (offset + size > m_out.bytes_written - m_out_bytes_used_for_exceptions)
|
while (offset + size > GetOutBytesWrittenExcludingExceptions())
|
||||||
{
|
{
|
||||||
u64 bytes_to_read;
|
u64 bytes_to_read;
|
||||||
if (offset + size == m_out.data.size())
|
if (offset + size == m_out.data.size())
|
||||||
|
@ -663,13 +663,13 @@ bool WIARVZFileReader<RVZ>::Chunk::Read(u64 offset, u64 size, u8* out_ptr)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Pick a suitable amount of compressed data to read. The std::min line has to
|
// Pick a suitable amount of compressed data to read. We have to ensure that bytes_to_read
|
||||||
// be as it is, but the rest is a bit arbitrary and can be changed if desired.
|
// is larger than 0 and smaller than or equal to the number of bytes available to read,
|
||||||
|
// but the rest is a bit arbitrary and could be changed.
|
||||||
|
|
||||||
// The compressed data is probably not much bigger than the decompressed data.
|
// The compressed data is probably not much bigger than the decompressed data.
|
||||||
// Add a few bytes for possible compression overhead and for any hash exceptions.
|
// Add a few bytes for possible compression overhead and for any hash exceptions.
|
||||||
bytes_to_read =
|
bytes_to_read = offset + size - GetOutBytesWrittenExcludingExceptions() + 0x100;
|
||||||
offset + size - (m_out.bytes_written - m_out_bytes_used_for_exceptions) + 0x100;
|
|
||||||
|
|
||||||
// Align the access in an attempt to gain speed. But we don't actually know the
|
// Align the access in an attempt to gain speed. But we don't actually know the
|
||||||
// block size of the underlying storage device, so we just use the Wii block size.
|
// block size of the underlying storage device, so we just use the Wii block size.
|
||||||
|
@ -839,6 +839,12 @@ void WIARVZFileReader<RVZ>::Chunk::GetHashExceptions(
|
||||||
m_in_bytes_used_for_exceptions));
|
m_in_bytes_used_for_exceptions));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <bool RVZ>
|
||||||
|
size_t WIARVZFileReader<RVZ>::Chunk::GetOutBytesWrittenExcludingExceptions() const
|
||||||
|
{
|
||||||
|
return m_exception_lists == 0 ? m_out.bytes_written - m_out_bytes_used_for_exceptions : 0;
|
||||||
|
}
|
||||||
|
|
||||||
template <bool RVZ>
|
template <bool RVZ>
|
||||||
bool WIARVZFileReader<RVZ>::ApplyHashExceptions(
|
bool WIARVZFileReader<RVZ>::ApplyHashExceptions(
|
||||||
const std::vector<HashExceptionEntry>& exception_list,
|
const std::vector<HashExceptionEntry>& exception_list,
|
||||||
|
|
|
@ -202,6 +202,8 @@ private:
|
||||||
bool HandleExceptions(const u8* data, size_t bytes_allocated, size_t bytes_written,
|
bool HandleExceptions(const u8* data, size_t bytes_allocated, size_t bytes_written,
|
||||||
size_t* bytes_used, bool align);
|
size_t* bytes_used, bool align);
|
||||||
|
|
||||||
|
size_t GetOutBytesWrittenExcludingExceptions() const;
|
||||||
|
|
||||||
DecompressionBuffer m_in;
|
DecompressionBuffer m_in;
|
||||||
DecompressionBuffer m_out;
|
DecompressionBuffer m_out;
|
||||||
size_t m_in_bytes_read = 0;
|
size_t m_in_bytes_read = 0;
|
||||||
|
|
Loading…
Reference in New Issue