diff options
author | Ivan Solovev <ivan.solovev@qt.io> | 2024-03-20 16:41:47 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2024-04-04 09:42:47 +0000 |
commit | 00e7e3c898af2b61434ef8f00d0c7cf2a821fdb2 (patch) | |
tree | 6de319da2b597f12d71a076ccda33aef1446f732 | |
parent | fec2a73d56dcaf245e1658843f3f1959d6ab3ad1 (diff) |
GeoClue2 plugin: fix a crash when geoclue-2.0 is not available
The problem is similar to the one that is fixed in
03a37f36b9d967205ec70c49ad21e438df362936.
If the geoclue-2.0 package is not installed, the system does not provide
the proper D-Bus services, and the attempt to create a client fails.
The sequence that leads to a crash is as follows:
- the QDBusPendingCallWatcher instance has a reply with an error
- it is wrapped in a QScopedPointer to control its lifetime
- when handling the error, the errorOccurred() signal is emitted
- the user application (SatelliteInfo example in this case) handles
the error and decides to switch the backend
- as a result, the QGeoPositionInfoSourceGeoclue2 instance is deleted
- after the signal is processed, we return to the lambda and try to
continue the execution, which leads to destruction of the scoped
pointer. The scoped pointer tries to delete its object, but it's
already deleted -> we get a crash.
Fix it by simplifying the processing of QDBusPendingCallWatcher. We
do not actually need the scoped pointer, we can just call deleteLater()
immediately, and copy the underlying reply.
Also fix the order of the client deletion and error setting in the
other code path, because it had the same problem.
As a drive-by, fix the warning message.
Fixes: QTBUG-115933
Fixes: QTBUG-121997
Pick-to: 6.6 6.5
Change-Id: If43ddc3a132d7b26e567bcf240fdad0ebbbdbf9b
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
(cherry picked from commit 8fdea76d36b0d2f88909e89de8823cc058625fe2)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2.cpp | 11 |
1 files changed, 5 insertions, 6 deletions
diff --git a/src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2.cpp b/src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2.cpp index 20ba7a9f..ba16ccac 100644 --- a/src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2.cpp +++ b/src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2.cpp @@ -216,13 +216,12 @@ void QGeoPositionInfoSourceGeoclue2::createClient() const auto watcher = new QDBusPendingCallWatcher(reply, this); connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) { - const QScopedPointer<QDBusPendingCallWatcher, QScopedPointerDeleteLater> - scopedWatcher(watcher); - const QDBusPendingReply<QDBusObjectPath> reply = *scopedWatcher; + watcher->deleteLater(); + const QDBusPendingReply<QDBusObjectPath> reply = *watcher; if (reply.isError()) { const auto error = reply.error(); - qCWarning(lcPositioningGeoclue2) << "Unable to obtain the client patch:" - << error.name() + error.message(); + qCWarning(lcPositioningGeoclue2) << "Unable to obtain the client:" + << error.name() << error.message(); setError(AccessError); } else { const QString clientPath = reply.value().path(); @@ -238,8 +237,8 @@ void QGeoPositionInfoSourceGeoclue2::createClient() const auto error = m_client->lastError(); qCCritical(lcPositioningGeoclue2) << "Unable to create the client object:" << error.name() << error.message(); - setError(AccessError); delete m_client; + setError(AccessError); } else { connect(m_client.data(), &OrgFreedesktopGeoClue2ClientInterface::LocationUpdated, this, &QGeoPositionInfoSourceGeoclue2::handleNewLocation); |