Fix a crash in ProxyAuthHandler (#5711)
authorckamm <mail@ckamm.de>
Thu, 20 Apr 2017 07:21:33 +0000 (09:21 +0200)
committerMarkus Goetz <markus@woboq.com>
Thu, 20 Apr 2017 07:21:33 +0000 (09:21 +0200)
See
https://sentry.io/owncloud/desktop-win-and-mac/issues/243433178/activity/
https://sentry.io/owncloud/desktop-win-and-mac/issues/234182688/activity/

The problem was that an account's QNetworkAccessManager can be deleted
when reentering the event loop.

src/gui/proxyauthhandler.cpp
src/libsync/account.cpp
src/libsync/account.h

index a3f0fba7e589eb51327a507d01f1de11db4e44d9..e80b540e806cb8418f8adfbfe11a8410d785f10b 100644 (file)
@@ -81,9 +81,14 @@ void ProxyAuthHandler::handleProxyAuthenticationRequired(
     }
 
     // Find the responsible QNAM if possible.
-    QNetworkAccessManager* sending_qnam = qobject_cast<QNetworkAccessManager*>(sender());
+    QNetworkAccessManager* sending_qnam = 0;
+    QWeakPointer<QNetworkAccessManager> qnam_alive;
     if (Account* account = qobject_cast<Account*>(sender())) {
-        sending_qnam = account->networkAccessManager();
+        // Since we go into an event loop, it's possible for the account's qnam
+        // to be destroyed before we get back. We can use this to check for its
+        // liveness.
+        qnam_alive = account->sharedNetworkAccessManager();
+        sending_qnam = qnam_alive.data();
     }
     if (!sending_qnam) {
         qDebug() << "Could not get the sending QNAM for" << sender();
@@ -122,6 +127,7 @@ void ProxyAuthHandler::handleProxyAuthenticationRequired(
     qDebug() << "got creds for" << _proxy;
     authenticator->setUser(_username);
     authenticator->setPassword(_password);
+    sending_qnam = qnam_alive.data();
     if (sending_qnam) {
         _gaveCredentialsTo.insert(sending_qnam);
         connect(sending_qnam, SIGNAL(destroyed(QObject*)),
index b926094598ee08ea68e51c6ad9d461ed06474bdd..34f0f374a34473ade016db0e40cb2bdf04a44e3c 100644 (file)
@@ -202,6 +202,11 @@ QNetworkAccessManager *Account::networkAccessManager()
     return _am.data();
 }
 
+QSharedPointer<QNetworkAccessManager> Account::sharedNetworkAccessManager()
+{
+    return _am;
+}
+
 QNetworkReply *Account::sendRequest(const QByteArray &verb, const QUrl &url, QNetworkRequest req, QIODevice *data)
 {
     req.setUrl(url);
index 0f55c5a1d758cfeb149dafa7bc2af59a7acf826d..1369b5df21ad9569ef11b8cf3f40aa0d30159af2 100644 (file)
@@ -185,6 +185,7 @@ public:
 
     void resetNetworkAccessManager();
     QNetworkAccessManager* networkAccessManager();
+    QSharedPointer<QNetworkAccessManager> sharedNetworkAccessManager();
 
     /// Called by network jobs on credential errors, emits invalidCredentials()
     void handleInvalidCredentials();