From c3cc2c92be595c19e434c4a6a204331ec793e469 Mon Sep 17 00:00:00 2001 From: "seer-by-sentry[bot]" <157164994+seer-by-sentry[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2026 23:04:56 +0000 Subject: [PATCH] fix: Prevent PlayerList::newGame array out-of-bounds and null dereferences --- .../Code/GameEngine/Source/Common/RTS/PlayerList.cpp | 9 +++++++++ .../Code/GameEngine/Source/Common/RTS/PlayerList.cpp | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/Generals/Code/GameEngine/Source/Common/RTS/PlayerList.cpp b/Generals/Code/GameEngine/Source/Common/RTS/PlayerList.cpp index 17dc7187f67..e326bce54e0 100644 --- a/Generals/Code/GameEngine/Source/Common/RTS/PlayerList.cpp +++ b/Generals/Code/GameEngine/Source/Common/RTS/PlayerList.cpp @@ -139,6 +139,12 @@ void PlayerList::newGame() if (pname.isEmpty()) continue; // it's neutral, which we've already done, so skip it. + if (m_playerCount >= MAX_PLAYER_COUNT) + { + DEBUG_ASSERTCRASH(false, ("Map has more player sides than MAX_PLAYER_COUNT (%d); skipping side '%s'", MAX_PLAYER_COUNT, pname.str())); + continue; + } + /// @todo The Player class should have a reset() method, instead of directly calling initFromDict() (MSB) Player* p = m_players[m_playerCount++]; p->initFromDict(d); @@ -188,6 +194,9 @@ void PlayerList::newGame() Dict *d = TheSidesList->getSideInfo(i)->getDict(); Player* p = findPlayerWithNameKey(NAMEKEY(d->getAsciiString(TheKey_playerName))); + if (!p) + continue; // player was skipped (e.g. side count exceeded MAX_PLAYER_COUNT) or is neutral with no name key. + AsciiString tok; AsciiString enemies = d->getAsciiString(TheKey_playerEnemies); diff --git a/GeneralsMD/Code/GameEngine/Source/Common/RTS/PlayerList.cpp b/GeneralsMD/Code/GameEngine/Source/Common/RTS/PlayerList.cpp index 1cf9041df97..e0c055280fc 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/RTS/PlayerList.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/RTS/PlayerList.cpp @@ -139,6 +139,12 @@ void PlayerList::newGame() if (pname.isEmpty()) continue; // it's neutral, which we've already done, so skip it. + if (m_playerCount >= MAX_PLAYER_COUNT) + { + DEBUG_ASSERTCRASH(false, ("Map has more player sides than MAX_PLAYER_COUNT (%d); skipping side '%s'", MAX_PLAYER_COUNT, pname.str())); + continue; + } + /// @todo The Player class should have a reset() method, instead of directly calling initFromDict() (MSB) Player* p = m_players[m_playerCount++]; p->initFromDict(d); @@ -188,6 +194,9 @@ void PlayerList::newGame() Dict *d = TheSidesList->getSideInfo(i)->getDict(); Player* p = findPlayerWithNameKey(NAMEKEY(d->getAsciiString(TheKey_playerName))); + if (!p) + continue; // player was skipped (e.g. side count exceeded MAX_PLAYER_COUNT) or is neutral with no name key. + AsciiString tok; AsciiString enemies = d->getAsciiString(TheKey_playerEnemies);