From: Christian Kamm Date: Thu, 6 Jul 2017 11:43:34 +0000 (+0200) Subject: Fix crash on account deletion X-Git-Tag: archive/raspbian/3.16.7-1_deb13u1+rpi1~1^2~704^2^2~68 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=d01065b9a12e69ca493a232f3a8e8f3d416fed52;p=nextcloud-desktop.git Fix crash on account deletion Calling forgetSensitiveData() on account deletion leads to a timer for clearQNAMCache() being queued. Then the Account object is deleted. The Credentials object stays alive for now because it has a deleteLater deleter. If the timer calls into a slot on the Credentials object, the _account pointer will be invalid at this time. As a workaround, move the target slot to Account - that way it will not be called as the account object is already destroyed. However since Account and Credentials are mutually dependent, it would be much preferable if their lifetimes were linked, avoiding this category of bugs. The current behavior was introduced in d40c56eda561e3a541bf1b23f70fa8d659d3037e and I currently don't understand why - maybe there's another way of dealing with the problem that existed then. --- diff --git a/src/libsync/account.cpp b/src/libsync/account.cpp index 39d15f971..19ace5ed0 100644 --- a/src/libsync/account.cpp +++ b/src/libsync/account.cpp @@ -391,6 +391,11 @@ void Account::handleInvalidCredentials() emit invalidCredentials(); } +void Account::clearQNAMCache() +{ + _am->clearAccessCache(); +} + const Capabilities &Account::capabilities() const { return _capabilities; diff --git a/src/libsync/account.h b/src/libsync/account.h index 4e554e590..66e0d1be6 100644 --- a/src/libsync/account.h +++ b/src/libsync/account.h @@ -197,6 +197,10 @@ public: /// Called by network jobs on credential errors, emits invalidCredentials() void handleInvalidCredentials(); +public slots: + /// Used when forgetting credentials + void clearQNAMCache(); + signals: /// Emitted whenever there's network activity void propagatorNetworkActivity(); diff --git a/src/libsync/creds/httpcredentials.cpp b/src/libsync/creds/httpcredentials.cpp index ce37ce93e..1670e0101 100644 --- a/src/libsync/creds/httpcredentials.cpp +++ b/src/libsync/creds/httpcredentials.cpp @@ -370,16 +370,7 @@ void HttpCredentials::invalidateToken() // indirectly) from QNetworkAccessManagerPrivate::authenticationRequired, which itself // is a called from a BlockingQueuedConnection from the Qt HTTP thread. And clearing the // cache needs to synchronize again with the HTTP thread. - QTimer::singleShot(0, this, SLOT(clearQNAMCache())); -} - -void HttpCredentials::clearQNAMCache() -{ -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) - _account->networkAccessManager()->clearAccessCache(); -#else - _account->resetNetworkAccessManager(); -#endif + QTimer::singleShot(0, _account, SLOT(clearQNAMCache())); } void HttpCredentials::forgetSensitiveData() diff --git a/src/libsync/creds/httpcredentials.h b/src/libsync/creds/httpcredentials.h index 45b01c5ee..03f3b8c70 100644 --- a/src/libsync/creds/httpcredentials.h +++ b/src/libsync/creds/httpcredentials.h @@ -110,7 +110,6 @@ private Q_SLOTS: void slotWriteClientCertPEMJobDone(QKeychain::Job *); void slotWriteClientKeyPEMJobDone(QKeychain::Job *); void slotWriteJobDone(QKeychain::Job *); - void clearQNAMCache(); protected: QString _user;