From 0c77ad9718bddcc63ed9143d178a2e550fa827e9 Mon Sep 17 00:00:00 2001 From: "seer-by-sentry[bot]" <157164994+seer-by-sentry[bot]@users.noreply.github.com> Date: Sat, 22 Nov 2025 14:52:48 +0000 Subject: [PATCH] PartitionManager: Add safety checks to prevent null pointer dereferences --- .../GameLogic/Object/PartitionManager.cpp | 30 +++++++++++++++++++ .../GameLogic/Object/PartitionManager.cpp | 30 +++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp index 6f6c228fd87..cb297486d2f 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp @@ -2979,6 +2979,12 @@ void PartitionManager::unRegisterGhostObject( GhostObject* object ) */ void PartitionManager::revealMapForPlayer( Int playerIndex ) { + // Safety check: ensure partition manager is properly initialized + if (m_cells == NULL || m_totalCellCount <= 0) + { + return; + } + // By looking and then stopping on every cell, I clear all Passive Shroud // By adding a looker directly I don't hit the Ally logic of the normal look/doShroudReveal for (int i = 0; i < m_totalCellCount; ++i) @@ -2993,6 +2999,12 @@ void PartitionManager::revealMapForPlayer( Int playerIndex ) */ void PartitionManager::revealMapForPlayerPermanently( Int playerIndex ) { + // Safety check: ensure partition manager is properly initialized + if (m_cells == NULL || m_totalCellCount <= 0) + { + return; + } + // By skipping the removeLooker, I consider myself as actively looking at everything, // so Shroud generation will no longer function // By adding a looker directly I don't hit the Ally logic of the normal look/doShroudReveal @@ -3007,6 +3019,12 @@ void PartitionManager::revealMapForPlayerPermanently( Int playerIndex ) */ void PartitionManager::undoRevealMapForPlayerPermanently( Int playerIndex ) { + // Safety check: ensure partition manager is properly initialized + if (m_cells == NULL || m_totalCellCount <= 0) + { + return; + } + //First make sure no lingering looks will leave holes when they aren't wanted. processEntirePendingUndoShroudRevealQueue(); @@ -3023,6 +3041,12 @@ void PartitionManager::undoRevealMapForPlayerPermanently( Int playerIndex ) */ void PartitionManager::shroudMapForPlayer( Int playerIndex ) { + // Safety check: ensure partition manager is properly initialized + if (m_cells == NULL || m_totalCellCount <= 0) + { + return; + } + //First make sure no lingering looks will leave holes when they aren't wanted. processEntirePendingUndoShroudRevealQueue(); @@ -3037,6 +3061,12 @@ void PartitionManager::shroudMapForPlayer( Int playerIndex ) //----------------------------------------------------------------------------- void PartitionManager::refreshShroudForLocalPlayer() { + // Safety check: ensure partition manager is properly initialized + if (m_cells == NULL || m_totalCellCount <= 0) + { + return; + } + // This is a drawing refresh only, and so is allowed to use the Local Player. TheDisplay->clearShroud(); TheRadar->clearShroud(); diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp index cb63f24eaa8..9e782dcf738 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp @@ -2986,6 +2986,12 @@ void PartitionManager::unRegisterGhostObject( GhostObject* object ) */ void PartitionManager::revealMapForPlayer( Int playerIndex ) { + // Safety check: ensure partition manager is properly initialized + if (m_cells == NULL || m_totalCellCount <= 0) + { + return; + } + // By looking and then stopping on every cell, I clear all Passive Shroud // By adding a looker directly I don't hit the Ally logic of the normal look/doShroudReveal for (int i = 0; i < m_totalCellCount; ++i) @@ -3000,6 +3006,12 @@ void PartitionManager::revealMapForPlayer( Int playerIndex ) */ void PartitionManager::revealMapForPlayerPermanently( Int playerIndex ) { + // Safety check: ensure partition manager is properly initialized + if (m_cells == NULL || m_totalCellCount <= 0) + { + return; + } + // By skipping the removeLooker, I consider myself as actively looking at everything, // so Shroud generation will no longer function // By adding a looker directly I don't hit the Ally logic of the normal look/doShroudReveal @@ -3014,6 +3026,12 @@ void PartitionManager::revealMapForPlayerPermanently( Int playerIndex ) */ void PartitionManager::undoRevealMapForPlayerPermanently( Int playerIndex ) { + // Safety check: ensure partition manager is properly initialized + if (m_cells == NULL || m_totalCellCount <= 0) + { + return; + } + //First make sure no lingering looks will leave holes when they aren't wanted. processEntirePendingUndoShroudRevealQueue(); @@ -3030,6 +3048,12 @@ void PartitionManager::undoRevealMapForPlayerPermanently( Int playerIndex ) */ void PartitionManager::shroudMapForPlayer( Int playerIndex ) { + // Safety check: ensure partition manager is properly initialized + if (m_cells == NULL || m_totalCellCount <= 0) + { + return; + } + //First make sure no lingering looks will leave holes when they aren't wanted. processEntirePendingUndoShroudRevealQueue(); @@ -3044,6 +3068,12 @@ void PartitionManager::shroudMapForPlayer( Int playerIndex ) //----------------------------------------------------------------------------- void PartitionManager::refreshShroudForLocalPlayer() { + // Safety check: ensure partition manager is properly initialized + if (m_cells == NULL || m_totalCellCount <= 0) + { + return; + } + // This is a drawing refresh only, and so is allowed to use the Local Player. TheDisplay->clearShroud(); TheRadar->clearShroud();