From efeb1f964d5ca621118d0534654483448887253c Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sat, 24 May 2025 13:18:01 +0200 Subject: [PATCH 1/3] [ZH] Fix crash in OpenContain::killAllContained() when killed occupants kill the host container --- .../GameLogic/Object/Contain/OpenContain.cpp | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp index 1ee432568c2..9e4226f4dd5 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp @@ -434,16 +434,26 @@ void OpenContain::removeAllContained( Bool exposeStealthUnits ) //------------------------------------------------------------------------------------------------- void OpenContain::killAllContained( void ) { - ContainedItemsList::iterator it = m_containList.begin(); + // TheSuperHackers @bugfix xezon 23/05/2025 Empty m_containList straight away + // to prevent a potential child call to catastrophically modify the m_containList as well. + // This scenario can happen if the killed occupant(s) apply deadly damage on death + // to the host container, which then attempts to remove all remaining occupants + // on the death of the host container. This is reproducible by shooting with + // Neutron Shells on a GLA Technical containing GLA Terrorists. + ContainedItemsList list; + list.swap(m_containList); + m_containListSize = 0; - while ( it != m_containList.end() ) + ContainedItemsList::iterator it = list.begin(); + + while ( it != list.end() ) { Object *rider = *it; - + DEBUG_ASSERTCRASH( rider, ("Contain list must not contain NULL element")); if ( rider ) { - it = m_containList.erase(it); + it = list.erase(it); m_containListSize--; onRemoving( rider ); @@ -472,6 +482,7 @@ void OpenContain::harmAndForceExitAllContained( DamageInfo *info ) { Object *rider = *it; + DEBUG_ASSERTCRASH( rider, ("Contain list must not contain NULL element")); if ( rider ) { removeFromContain( rider, true ); @@ -490,7 +501,7 @@ void OpenContain::harmAndForceExitAllContained( DamageInfo *info ) DEBUG_ASSERTCRASH( m_containListSize == 0, ("harmAndForceExitAllContained just made a booboo, list size != zero.") ); -} // end removeAllContained +} // end harmAndForceExitAllContained //------------------------------------------------------------------------------------------------- From 4cad2cbcc98e927b3ec7a34fef1b661ddd0adf55 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Fri, 30 May 2025 10:57:36 +0200 Subject: [PATCH 2/3] Fix EA comment --- .../GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp index 9e4226f4dd5..c604319d643 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp @@ -469,7 +469,7 @@ void OpenContain::killAllContained( void ) DEBUG_ASSERTCRASH( m_containListSize == 0, ("killallcontain just made a booboo, list size != zero.") ); -} // end removeAllContained +} // end killAllContained //-------------------------------------------------------------------------------------------------------- /** Force all contained objects in the contained list to exit, and kick them in the pants on the way out*/ From 3c28d9ffa4d17fe80f32c95b4057ada705d0c6f0 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Fri, 30 May 2025 11:29:23 +0200 Subject: [PATCH 3/3] Fix m_containListSize count in OpenContain::killAllContained --- .../GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp index c604319d643..4bb528e6c12 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp @@ -454,7 +454,6 @@ void OpenContain::killAllContained( void ) if ( rider ) { it = list.erase(it); - m_containListSize--; onRemoving( rider ); rider->onRemovedFrom( getObject() );