diff options
author | Robert Griebl <robert.griebl@qt.io> | 2022-08-05 00:34:12 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2022-08-05 11:22:43 +0000 |
commit | 8af68bc0963fd9c865456968234fa7e9a7439504 (patch) | |
tree | 30f9b61baab7da8bf753e7481c649b571a8fb62f | |
parent | 5871b8bda923f567d984d1f68d13987769006411 (diff) | |
download | qtapplicationmanager-8af68bc0963fd9c865456968234fa7e9a7439504.tar.gz |
Intents: prevent a crash if a sent request is gc'ed too early
Not saving the result of IntentClient.sendIntentRequest could lead to
the GC deleting the IntentClientRequest before it was even delivered
to the receiver, leaving a dangling pointer.
Change-Id: I8972795d166fa46dd736005dd4df33b9a7ea2463
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Bernd Weimer <bernd.weimer@qt.io>
(cherry picked from commit bb186192373c6ff796c9084f22d48b02d14886c7)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/intent-client-lib/intentclient.cpp | 11 | ||||
-rw-r--r-- | src/intent-client-lib/intentclient.h | 4 | ||||
-rw-r--r-- | src/manager-lib/intentaminterface.cpp | 3 |
3 files changed, 15 insertions, 3 deletions
diff --git a/src/intent-client-lib/intentclient.cpp b/src/intent-client-lib/intentclient.cpp index 97dacc61..08fbd92f 100644 --- a/src/intent-client-lib/intentclient.cpp +++ b/src/intent-client-lib/intentclient.cpp @@ -112,6 +112,7 @@ IntentClient::IntentClient(IntentClientSystemInterface *systemInterface, QObject : QObject(parent) , m_systemInterface(systemInterface) { + m_lastWaitingCleanup.start(); m_systemInterface->setParent(this); } @@ -223,8 +224,8 @@ void IntentClient::replyFromSystem(const QUuid &requestId, bool error, const QVa { IntentClientRequest *icr = nullptr; auto it = std::find_if(m_waiting.cbegin(), m_waiting.cend(), - [requestId](IntentClientRequest *ir) -> bool { - return (ir->requestId() == requestId); + [requestId](const QPointer<IntentClientRequest> &ir) -> bool { + return ir && (ir->requestId() == requestId); }); if (it == m_waiting.cend()) { @@ -236,6 +237,12 @@ void IntentClient::replyFromSystem(const QUuid &requestId, bool error, const QVa icr = *it; m_waiting.erase(it); + // make sure to periodically remove all requests that were gc'ed before a reply was received + if (m_lastWaitingCleanup.elapsed() > 1000) { + m_waiting.removeAll({ }); + m_lastWaitingCleanup.start(); + } + if (error) icr->setErrorMessage(result.value(qSL("errorMessage")).toString()); else diff --git a/src/intent-client-lib/intentclient.h b/src/intent-client-lib/intentclient.h index 59128c6d..dac1733b 100644 --- a/src/intent-client-lib/intentclient.h +++ b/src/intent-client-lib/intentclient.h @@ -37,6 +37,7 @@ #include <QList> #include <QMap> #include <QPair> +#include <QElapsedTimer> #include <QtAppManCommon/global.h> @@ -88,7 +89,8 @@ private: Q_DISABLE_COPY(IntentClient) static IntentClient *s_instance; - QList<IntentClientRequest *> m_waiting; + QList<QPointer<IntentClientRequest>> m_waiting; + QElapsedTimer m_lastWaitingCleanup; QMap<QPair<QString, QString>, IntentHandler *> m_handlers; // intentId + appId -> handler // no timeouts by default -- these have to be set at runtime diff --git a/src/manager-lib/intentaminterface.cpp b/src/manager-lib/intentaminterface.cpp index 7a06a968..7ab0ad38 100644 --- a/src/manager-lib/intentaminterface.cpp +++ b/src/manager-lib/intentaminterface.cpp @@ -301,6 +301,9 @@ void IntentClientAMImplementation::requestToSystem(QPointer<IntentClientRequest> // on app startup and (b) have consistent behavior in single- and multi-process mode QMetaObject::invokeMethod(m_ic, [icr, this]() { + if (!icr) + return; + IntentServerRequest *isr = m_issi->requestToSystem(icr->requestingApplicationId(), icr->intentId(), icr->applicationId(), icr->parameters()); QUuid requestId = isr ? isr->requestId() : QUuid(); |