diff --git a/Generals/Code/GameEngine/Source/GameClient/System/CampaignManager.cpp b/Generals/Code/GameEngine/Source/GameClient/System/CampaignManager.cpp index 66d1c4d9d17..f4af70002f8 100644 --- a/Generals/Code/GameEngine/Source/GameClient/System/CampaignManager.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/System/CampaignManager.cpp @@ -186,7 +186,30 @@ Mission *Campaign::getNextMission( Mission *current) name = m_firstMission; } else + { + // Validate that current still points to a valid mission in our list + // to prevent use-after-free crashes + Bool foundCurrent = FALSE; + MissionListIt validateIt = m_missions.begin(); + while(validateIt != m_missions.end()) + { + if(*validateIt == current) + { + foundCurrent = TRUE; + break; + } + ++validateIt; + } + + // If current mission is not in our list anymore, it may have been freed + if(!foundCurrent) + { + DEBUG_LOG(("Campaign::getNextMission - current mission pointer is not in mission list, possible use-after-free")); + return NULL; + } + name = current->m_nextMission; + } name.toLower(); MissionListIt it; it = m_missions.begin(); diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/System/CampaignManager.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/System/CampaignManager.cpp index 9f7b5770346..4f7837ae1ff 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/System/CampaignManager.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/System/CampaignManager.cpp @@ -193,7 +193,30 @@ Mission *Campaign::getNextMission( Mission *current) name = m_firstMission; } else + { + // Validate that current still points to a valid mission in our list + // to prevent use-after-free crashes + Bool foundCurrent = FALSE; + MissionListIt validateIt = m_missions.begin(); + while(validateIt != m_missions.end()) + { + if(*validateIt == current) + { + foundCurrent = TRUE; + break; + } + ++validateIt; + } + + // If current mission is not in our list anymore, it may have been freed + if(!foundCurrent) + { + DEBUG_LOG(("Campaign::getNextMission - current mission pointer is not in mission list, possible use-after-free")); + return NULL; + } + name = current->m_nextMission; + } name.toLower(); MissionListIt it; it = m_missions.begin();