From f442d69cb68dc124e46b59655559f0b1b7cc99db Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 28 Nov 2023 21:23:27 +0400 Subject: [PATCH] Fix possible crash on MTProto instance shutdown. --- Telegram/SourceFiles/mtproto/mtp_instance.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/Telegram/SourceFiles/mtproto/mtp_instance.cpp b/Telegram/SourceFiles/mtproto/mtp_instance.cpp index 1794fe8b2c..e5b5cc8ec8 100644 --- a/Telegram/SourceFiles/mtproto/mtp_instance.cpp +++ b/Telegram/SourceFiles/mtproto/mtp_instance.cpp @@ -1134,9 +1134,10 @@ void Instance::Private::processCallback(const Response &response) { QString::number(error.code()), error.type(), error.description())); - if (rpcErrorOccured(response, handler, error)) { + const auto guard = QPointer(_instance); + if (rpcErrorOccured(response, handler, error) && guard) { unregisterRequest(requestId); - } else { + } else if (guard) { QMutexLocker locker(&_parserMapLock); _parserMap.emplace(requestId, std::move(handler)); } @@ -1156,12 +1157,15 @@ void Instance::Private::processCallback(const Response &response) { "RESPONSE_PARSE_FAILED", "Error parse failed."))); } else { - if (handler.done && !handler.done(response)) { + const auto guard = QPointer(_instance); + if (handler.done && !handler.done(response) && guard) { handleError(Error::Local( "RESPONSE_PARSE_FAILED", "Response parse failed.")); } - unregisterRequest(requestId); + if (guard) { + unregisterRequest(requestId); + } } } else { DEBUG_LOG(("RPC Info: parser not found for %1").arg(requestId)); @@ -1192,8 +1196,11 @@ bool Instance::Private::rpcErrorOccured( const FailHandler &onFail, const Error &error) { // return true if need to clean request data if (IsDefaultHandledError(error)) { + const auto guard = QPointer(_instance); if (onFail && onFail(error, response)) { return true; + } else if (!guard) { + return false; } } @@ -1208,7 +1215,11 @@ bool Instance::Private::rpcErrorOccured( ? QString() : QString(": %1").arg(error.description()))); if (onFail) { + const auto guard = QPointer(_instance); onFail(error, response); + if (!guard) { + return false; + } } return true; }