From 486c1b45831e90bc50a52cb30a50346659168286 Mon Sep 17 00:00:00 2001 From: "seer-by-sentry[bot]" <157164994+seer-by-sentry[bot]@users.noreply.github.com> Date: Sun, 19 Apr 2026 02:21:34 +0000 Subject: [PATCH] bugfix(overridable): Prevent dangling pointer after removing override chain --- Generals/Code/GameEngine/Include/Common/Overridable.h | 9 +++++++++ GeneralsMD/Code/GameEngine/Include/Common/Overridable.h | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/Generals/Code/GameEngine/Include/Common/Overridable.h b/Generals/Code/GameEngine/Include/Common/Overridable.h index 30105265b27..6f782cb557f 100644 --- a/Generals/Code/GameEngine/Include/Common/Overridable.h +++ b/Generals/Code/GameEngine/Include/Common/Overridable.h @@ -105,6 +105,15 @@ class Overridable : public MemoryPoolObject { if ( m_isOverride ) { + // TheSuperHackers @bugfix Clean up the override chain before deleting this node. + // Without this, deleteInstance(this) triggers ~Overridable() which deletes m_nextOverride + // via the destructor, but the caller may still hold a pointer to the now-freed chain, + // creating a dangling pointer that causes an access violation in getFinalOverride(). + if ( m_nextOverride ) + { + m_nextOverride->deleteOverrides(); + m_nextOverride = nullptr; + } deleteInstance(this); return nullptr; } diff --git a/GeneralsMD/Code/GameEngine/Include/Common/Overridable.h b/GeneralsMD/Code/GameEngine/Include/Common/Overridable.h index 1200927bd6d..0a47a6652cb 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/Overridable.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/Overridable.h @@ -105,6 +105,15 @@ class Overridable : public MemoryPoolObject { if ( m_isOverride ) { + // TheSuperHackers @bugfix Clean up the override chain before deleting this node. + // Without this, deleteInstance(this) triggers ~Overridable() which deletes m_nextOverride + // via the destructor, but the caller may still hold a pointer to the now-freed chain, + // creating a dangling pointer that causes an access violation in getFinalOverride(). + if ( m_nextOverride ) + { + m_nextOverride->deleteOverrides(); + m_nextOverride = nullptr; + } deleteInstance(this); return nullptr; }