diff --git a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GeneralsOnline/HTTP/HTTPRequest.h b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GeneralsOnline/HTTP/HTTPRequest.h index 66ee38bc19c..59ff0402288 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GeneralsOnline/HTTP/HTTPRequest.h +++ b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GeneralsOnline/HTTP/HTTPRequest.h @@ -59,6 +59,14 @@ class HTTPRequest std::string GetURI() { return m_strURI; } + // Clear callbacks to prevent use-after-free during shutdown + void ClearCallbacks() + { + m_completionCallback = nullptr; + m_progressCallback = nullptr; + } + + private: void PlatformStartRequest(); @@ -97,4 +105,4 @@ class HTTPRequest std::function m_completionCallback = nullptr; std::function m_progressCallback = nullptr; -}; +}; diff --git a/GeneralsMD/Code/GameEngine/Source/GameNetwork/GeneralsOnline/HTTP/HTTPManager.cpp b/GeneralsMD/Code/GameEngine/Source/GameNetwork/GeneralsOnline/HTTP/HTTPManager.cpp index 8ac79982f8b..bf3f79807ef 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameNetwork/GeneralsOnline/HTTP/HTTPManager.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameNetwork/GeneralsOnline/HTTP/HTTPManager.cpp @@ -67,6 +67,16 @@ void HTTPManager::Shutdown() NetworkLog(ELogVerbosity::LOG_RELEASE, "[HTTPManager] Waiting for %d in-flight requests to complete...", (int)m_vecRequestsInFlight.size()); + // Clear all callbacks on in-flight requests to prevent use-after-free + // when callbacks are invoked during shutdown with dangling pointers + for (HTTPRequest* pRequest : m_vecRequestsInFlight) + { + if (pRequest != nullptr) + { + pRequest->ClearCallbacks(); + } + } + // Wait for all in-flight requests to complete if (m_pCurl != nullptr) {