bugfix(aigroup): Prevent game crash when a player is selected in Replay playback (2)#2711
Conversation
29b2761 to
2909a9e
Compare
|
| Filename | Overview |
|---|---|
| Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp | Replaces unsafe use-after-free guard (getCount() == 0) with TheAI->doesGroupExist(), preventing dereference of freed memory. |
| Generals/Code/GameEngine/Include/GameLogic/AI.h | Adds doesGroupExist declaration to the Generals build header, needed for compilation under RETAIL_COMPATIBLE_AIGROUP. |
| Generals/Code/GameEngine/Source/GameLogic/AI/AI.cpp | Implements doesGroupExist via a pointer-identity search of m_groupList — no dereference of the candidate pointer. |
| GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h | Adds doesGroupExist declaration to the Zero Hour build header, mirroring the Generals change. |
| GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AI.cpp | Implements doesGroupExist for Zero Hour, identical to the Generals implementation. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[logicMessageDispatcher called] --> B{currentlySelectedGroup != null?}
B -- No --> Z[Continue to destroyGroup block]
B -- Yes --> C{TheAI->doesGroupExist currentlySelectedGroup?}
C -- No: group was freed --> R[return early — use-after-free avoided]
C -- Yes: group is live --> D[Safe to dereference: currentlySelectedGroup->getAllIDs]
D --> E[Deselect / reselect drawables]
E --> Z
Z --> F{currentlySelectedGroup != null?}
F -- Yes --> G[TheAI->destroyGroup — group still in list]
F -- No --> H[End]
G --> H
Reviews (4): Last reviewed commit: "Made 'AI::doesGroupExist' member functio..." | Re-trigger Greptile
xezon
left a comment
There was a problem hiding this comment.
Makes sense. I have not thought of that.
|
Replicated in Generals. |
5429a2a to
c5f8c47
Compare
|
Rebased to include the fix for the CI Replay checker. |
With the fix from #1212
AIGroupPtr currentlySelectedGroupwould be accessed even if it had been destroyed and its memory deallocated. This is a use-after-free bug. It relies on the memory not being overwritten on deallocation.If macro
MEMORYPOOL_DEBUG(enabled byRTS_DEBUG) is enabled, freed memory is overwritten with a garbage value, so the game crashes whencurrentlySelectedGroupis dereferenced (at line 2132).TODO: