From fd53ca35002974a498685aabe25c171228c33418 Mon Sep 17 00:00:00 2001 From: "seer-by-sentry[bot]" <157164994+seer-by-sentry[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 11:39:52 +0000 Subject: [PATCH] Fix: Prevent use-after-free in HTTPRequest completion callback --- .../GameNetwork/GeneralsOnline/HTTP/HTTPRequest.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/GeneralsMD/Code/GameEngine/Source/GameNetwork/GeneralsOnline/HTTP/HTTPRequest.cpp b/GeneralsMD/Code/GameEngine/Source/GameNetwork/GeneralsOnline/HTTP/HTTPRequest.cpp index 77800d9017f..2cf9b82e9c2 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameNetwork/GeneralsOnline/HTTP/HTTPRequest.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameNetwork/GeneralsOnline/HTTP/HTTPRequest.cpp @@ -100,6 +100,14 @@ void HTTPRequest::InvokeCallbackIfComplete() { if (m_completionCallback != nullptr) { + // Move the callback into a local variable and clear the member before + // invoking it. This prevents a use-after-free: the HTTPRequest may be + // deleted (by HTTPManager::Tick) immediately after this call returns, + // which would run ~HTTPRequest and destroy m_completionCallback's + // captured state while it is still on the call stack. + auto callback = std::move(m_completionCallback); + m_completionCallback = nullptr; + // Convert m_vecBuffer to std::string for m_strResponse std::string strResponse; if (!m_vecBuffer.empty() && m_currentBufSize_Used > 0) @@ -110,7 +118,7 @@ void HTTPRequest::InvokeCallbackIfComplete() { strResponse.clear(); } - m_completionCallback(true, m_responseCode, strResponse, this); + callback(true, m_responseCode, strResponse, this); } } }