Skip to content

Commit 86587a8

Browse files
authored
[ZH] Fix crash in TunnelContain::killAllContained() when killed occupants kill the host container (#1006)
1 parent 74b42c4 commit 86587a8

File tree

3 files changed

+25
-8
lines changed

3 files changed

+25
-8
lines changed

GeneralsMD/Code/GameEngine/Include/Common/TunnelTracker.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class TunnelTracker : public MemoryPoolObject,
4949
UnsignedInt getContainCount() const { return m_containListSize; }
5050
Int getContainMax() const;
5151
const ContainedItemsList* getContainedItemsList() const { return &m_containList; }
52+
void swapContainedItemsList(ContainedItemsList& newList);
5253

5354
Bool isValidContainerFor(const Object* obj, Bool checkCapacity) const;
5455
void addToContainList( Object *obj ); ///< add 'obj' to contain list

GeneralsMD/Code/GameEngine/Source/Common/RTS/TunnelTracker.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,13 @@ Int TunnelTracker::getContainMax() const
107107
return TheGlobalData->m_maxTunnelCapacity;
108108
}
109109

110+
// ------------------------------------------------------------------------
111+
void TunnelTracker::swapContainedItemsList(ContainedItemsList& newList)
112+
{
113+
m_containList.swap(newList);
114+
m_containListSize = (Int)m_containList.size();
115+
}
116+
110117
// ------------------------------------------------------------------------
111118
void TunnelTracker::updateNemesis(const Object *target)
112119
{

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

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -149,18 +149,27 @@ void TunnelContain::harmAndForceExitAllContained( DamageInfo *info )
149149
//-------------------------------------------------------------------------------------------------
150150
void TunnelContain::killAllContained( void )
151151
{
152+
// TheSuperHackers @bugfix xezon 04/06/2025 Empty the TunnelSystem's Contained Items List
153+
// straight away to prevent a potential child call to catastrophically modify it as well.
154+
// This scenario can happen if the killed occupant(s) apply deadly damage on death
155+
// to the host container, which then attempts to remove all remaining occupants
156+
// on the death of the host container. This is reproducible by shooting with
157+
// Neutron Shells on a GLA Tunnel containing GLA Terrorists.
158+
159+
ContainedItemsList list;
152160
Player *owningPlayer = getObject()->getControllingPlayer();
153-
const ContainedItemsList *fullList = owningPlayer->getTunnelSystem()->getContainedItemsList();
161+
owningPlayer->getTunnelSystem()->swapContainedItemsList(list);
154162

155-
Object *obj;
156-
ContainedItemsList::const_iterator it;
157-
it = (*fullList).begin();
158-
while( it != (*fullList).end() )
163+
ContainedItemsList::iterator it = list.begin();
164+
165+
while ( it != list.end() )
159166
{
160-
obj = *it;
161-
it++;
167+
Object *obj = *it++;
168+
DEBUG_ASSERTCRASH( obj, ("Contain list must not contain NULL element"));
169+
162170
removeFromContain( obj, true );
163-
obj->kill();
171+
172+
obj->kill();
164173
}
165174
}
166175
//-------------------------------------------------------------------------------------------------

0 commit comments

Comments
 (0)