Skip to content

Replay playback dereferences a null slot when the local player index is -1 #3239

Description

@bobtista

RecorderClass::playbackFile determines whether the recorded game was multiplayer by reading the local player slot:

Bool isMultiplayer = m_gameInfo.getSlot(header.localPlayerIndex)->getIP() != 0;

readReplayHeader accepts -1 as a valid local player index, and GameInfo::getSlot returns nullptr for a negative slot, so a replay carrying -1 crashes before playback begins.

This dereference was introduced by #545 when replay CRC handling began distinguishing network games from local games. Before #545, the local player index was stored without accessing its slot.

The -1 value remains supported by the replay parser and can occur in legacy or externally generated replays. The LAN and GameSpy recording paths can also preserve the default -1 if they fail to identify the local slot, although those paths have not been reproduced.

The replay stores its original game mode after the header, so GAME_LAN and GAME_INTERNET can identify network replays without reading the local slot. This also preserves the correct replay CRC alignment when a network replay has no local slot.

This affects every replay entry point using RecorderClass::playbackFile, including the Replay menu.

GameLogic::startNewGame dereferences the same missing slot a second time, and this one is what actually ends the process:

d.setBool(TheKey_multiplayerIsLocal, slot->isHuman() && (slot->getName().compare(TheGameInfo->getSlot(TheGameInfo->getLocalSlotNum())->getName().str()) == 0));

readReplayHeader only calls setLocalIP when the index is not negative, so a replay carrying -1 leaves the local IP unset, getLocalSlotNum matches no slot and returns -1, and the lookup dereferences nullptr. A replay byte-edited to carry -1 crashes here with EXCEPTION_ACCESS_VIOLATION reading address 0x28, and the log records GameInfo::getSlot - Invalid slot number immediately before the dump.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugSomething is not working right, typically is user facingSaveloadIs Saveload/Xfer related

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions