From 8ac385f91cc2f70d1218ad8f7a813c63ee7b160f Mon Sep 17 00:00:00 2001 From: Caball009 <82909616+Caball009@users.noreply.github.com> Date: Fri, 7 Aug 2026 17:31:19 +0200 Subject: [PATCH] bugfix(replay): Validate next frame value for replay playback. --- .../Code/GameEngine/Source/Common/Recorder.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp b/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp index 2d9bfea3a16..23723347a81 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp @@ -1277,8 +1277,19 @@ AsciiString RecorderClass::readAsciiString() { */ void RecorderClass::readNextFrame() { Int bytesRead = m_file->read(&m_nextFrame, sizeof(m_nextFrame)); - if (bytesRead != sizeof(m_nextFrame)) { - DEBUG_LOG(("RecorderClass::readNextFrame - read failed on frame %d", TheGameLogic->getFrame())); + + // TheSuperHackers @bugfix Check whether the next frame value is within a reasonable range + // to avoid prolonging playback due to potentially corrupted data. + const Bool validFrameValue = (m_mode == RECORDERMODETYPE_NONE + || (m_nextFrame >= TheGameLogic->getFrame() && m_nextFrame < TheGameLogic->getFrame() + 3600 * LOGICFRAMES_PER_SECOND)); + + if (bytesRead != sizeof(m_nextFrame) || !validFrameValue) { + if (bytesRead != sizeof(m_nextFrame)) { + DEBUG_LOG(("RecorderClass::readNextFrame - read failed on frame %d", TheGameLogic->getFrame())); + } else { + DEBUG_CRASH(("RecorderClass::readNextFrame - current frame %d, next frame %d in the replay appears invalid", + TheGameLogic->getFrame(), m_nextFrame)); + } m_nextFrame = -1; stopPlayback(); }