Skip to content

Commit f603a12

Browse files
authored
[ZH] Fix crash in OpenContain::killAllContained() when killed occupants kill the host container (#921)
1 parent 9e2df4e commit f603a12

File tree

1 file changed

+17
-7
lines changed

1 file changed

+17
-7
lines changed

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -434,17 +434,26 @@ void OpenContain::removeAllContained( Bool exposeStealthUnits )
434434
//-------------------------------------------------------------------------------------------------
435435
void OpenContain::killAllContained( void )
436436
{
437-
ContainedItemsList::iterator it = m_containList.begin();
437+
// TheSuperHackers @bugfix xezon 23/05/2025 Empty m_containList straight away
438+
// to prevent a potential child call to catastrophically modify the m_containList as well.
439+
// This scenario can happen if the killed occupant(s) apply deadly damage on death
440+
// to the host container, which then attempts to remove all remaining occupants
441+
// on the death of the host container. This is reproducible by shooting with
442+
// Neutron Shells on a GLA Technical containing GLA Terrorists.
443+
ContainedItemsList list;
444+
list.swap(m_containList);
445+
m_containListSize = 0;
438446

439-
while ( it != m_containList.end() )
447+
ContainedItemsList::iterator it = list.begin();
448+
449+
while ( it != list.end() )
440450
{
441451
Object *rider = *it;
442452

443-
453+
DEBUG_ASSERTCRASH( rider, ("Contain list must not contain NULL element"));
444454
if ( rider )
445455
{
446-
it = m_containList.erase(it);
447-
m_containListSize--;
456+
it = list.erase(it);
448457

449458
onRemoving( rider );
450459
rider->onRemovedFrom( getObject() );
@@ -459,7 +468,7 @@ void OpenContain::killAllContained( void )
459468

460469
DEBUG_ASSERTCRASH( m_containListSize == 0, ("killallcontain just made a booboo, list size != zero.") );
461470

462-
} // end removeAllContained
471+
} // end killAllContained
463472

464473
//--------------------------------------------------------------------------------------------------------
465474
/** Force all contained objects in the contained list to exit, and kick them in the pants on the way out*/
@@ -472,6 +481,7 @@ void OpenContain::harmAndForceExitAllContained( DamageInfo *info )
472481
{
473482
Object *rider = *it;
474483

484+
DEBUG_ASSERTCRASH( rider, ("Contain list must not contain NULL element"));
475485
if ( rider )
476486
{
477487
removeFromContain( rider, true );
@@ -490,7 +500,7 @@ void OpenContain::harmAndForceExitAllContained( DamageInfo *info )
490500

491501
DEBUG_ASSERTCRASH( m_containListSize == 0, ("harmAndForceExitAllContained just made a booboo, list size != zero.") );
492502

493-
} // end removeAllContained
503+
} // end harmAndForceExitAllContained
494504

495505

496506
//-------------------------------------------------------------------------------------------------

0 commit comments

Comments
 (0)