diff --git a/Source/Core/Common/ChunkFile.h b/Source/Core/Common/ChunkFile.h index a9737c1e0e..7ae4d7e778 100644 --- a/Source/Core/Common/ChunkFile.h +++ b/Source/Core/Common/ChunkFile.h @@ -288,7 +288,7 @@ public: } template - void DoPointer(T*& x, T* const base) + bool DoPointer(T*& x, T* const base, size_t count) { // pointers can be more than 2^31 apart, but you're using this function wrong if you need that // much range @@ -296,15 +296,23 @@ public: Do(offset); if (IsReadMode()) { + if (offset < 0 || static_cast(offset) > count) + { + SetMeasureMode(); + return false; + } x = base + offset; } + return true; } - void DoPointer(void*& x, void* const base) + bool DoPointer(void*& x, void* const base, size_t count) { auto* ptr = static_cast(x); - DoPointer(ptr, static_cast(base)); + if (!DoPointer(ptr, static_cast(base), count)) + return false; x = ptr; + return true; } void DoMarker(const std::string& prevName, u32 arbitraryNumber = 0x42) diff --git a/Source/Core/VideoCommon/Fifo.cpp b/Source/Core/VideoCommon/Fifo.cpp index f183c93655..d396d318c9 100644 --- a/Source/Core/VideoCommon/Fifo.cpp +++ b/Source/Core/VideoCommon/Fifo.cpp @@ -54,9 +54,16 @@ void FifoManager::DoState(PointerWrap& p) { p.DoArray(m_video_buffer, FIFO_SIZE); u8* write_ptr = m_video_buffer_write_ptr; - p.DoPointer(write_ptr, m_video_buffer); + if (!p.DoPointer(write_ptr, m_video_buffer, FIFO_SIZE)) + return; m_video_buffer_write_ptr = write_ptr; - p.DoPointer(m_video_buffer_read_ptr, m_video_buffer); + if (!p.DoPointer(m_video_buffer_read_ptr, m_video_buffer, FIFO_SIZE)) + return; + if (p.IsReadMode() && m_video_buffer_read_ptr > write_ptr) + { + p.SetMeasureMode(); + return; + } if (p.IsReadMode() && m_use_deterministic_gpu_thread) { // We're good and paused, right?