Add null httpReply checks to QHttpThreadDelegate
authorShane Kearns <ext-shane.2.kearns@nokia.com>
Thu, 28 Jun 2012 13:52:45 +0000 (14:52 +0100)
committerQt by Nokia <qt-info@nokia.com>
Mon, 2 Jul 2012 23:09:25 +0000 (01:09 +0200)
If a request is aborted while under load, the abort signal can be
queued in front of a signal emitted from the httpReply.
The abort slot is deleting the httpReply and setting it to null.
So when the queued slot is processed the httpReply is null and
caused an MMU fault.

Removed qWarning from existing null checks, as these are expected
if abort is called with precise timing so that it races with the
reply finishing on the socket.

Task-number: QTBUG-26245
Change-Id: I0a7e0223fda1bc01d117fe8a993c7f6e43fd72ff
Reviewed-by: Jonas Gastal <jgastal@profusion.mobi>
Reviewed-by: Richard J. Moore <rich@kde.org>
src/network/access/qhttpthreaddelegate.cpp

index 0a2d595..1cef9f2 100644 (file)
@@ -411,10 +411,9 @@ void QHttpThreadDelegate::readyReadSlot()
 
 void QHttpThreadDelegate::finishedSlot()
 {
-    if (!httpReply) {
-        qWarning("QHttpThreadDelegate::finishedSlot: HTTP reply had already been deleted, internal problem. Please report.");
+    if (!httpReply)
         return;
-    }
+
 #ifdef QHTTPTHREADDELEGATE_DEBUG
     qDebug() << "QHttpThreadDelegate::finishedSlot() thread=" << QThread::currentThreadId() << "result=" << httpReply->statusCode();
 #endif
@@ -447,6 +446,9 @@ void QHttpThreadDelegate::finishedSlot()
 
 void QHttpThreadDelegate::synchronousFinishedSlot()
 {
+    if (!httpReply)
+        return;
+
 #ifdef QHTTPTHREADDELEGATE_DEBUG
     qDebug() << "QHttpThreadDelegate::synchronousFinishedSlot() thread=" << QThread::currentThreadId() << "result=" << httpReply->statusCode();
 #endif
@@ -467,10 +469,9 @@ void QHttpThreadDelegate::synchronousFinishedSlot()
 
 void QHttpThreadDelegate::finishedWithErrorSlot(QNetworkReply::NetworkError errorCode, const QString &detail)
 {
-    if (!httpReply) {
-        qWarning("QHttpThreadDelegate::finishedWithErrorSlot: HTTP reply had already been deleted, internal problem. Please report.");
+    if (!httpReply)
         return;
-    }
+
 #ifdef QHTTPTHREADDELEGATE_DEBUG
     qDebug() << "QHttpThreadDelegate::finishedWithErrorSlot() thread=" << QThread::currentThreadId() << "error=" << errorCode << detail;
 #endif
@@ -491,6 +492,9 @@ void QHttpThreadDelegate::finishedWithErrorSlot(QNetworkReply::NetworkError erro
 
 void QHttpThreadDelegate::synchronousFinishedWithErrorSlot(QNetworkReply::NetworkError errorCode, const QString &detail)
 {
+    if (!httpReply)
+        return;
+
 #ifdef QHTTPTHREADDELEGATE_DEBUG
     qDebug() << "QHttpThreadDelegate::synchronousFinishedWithErrorSlot() thread=" << QThread::currentThreadId() << "error=" << errorCode << detail;
 #endif
@@ -509,6 +513,9 @@ static void downloadBufferDeleter(char *ptr)
 
 void QHttpThreadDelegate::headerChangedSlot()
 {
+    if (!httpReply)
+        return;
+
 #ifdef QHTTPTHREADDELEGATE_DEBUG
     qDebug() << "QHttpThreadDelegate::headerChangedSlot() thread=" << QThread::currentThreadId();
 #endif
@@ -549,6 +556,9 @@ void QHttpThreadDelegate::headerChangedSlot()
 
 void QHttpThreadDelegate::synchronousHeaderChangedSlot()
 {
+    if (!httpReply)
+        return;
+
 #ifdef QHTTPTHREADDELEGATE_DEBUG
     qDebug() << "QHttpThreadDelegate::synchronousHeaderChangedSlot() thread=" << QThread::currentThreadId();
 #endif
@@ -581,6 +591,9 @@ void QHttpThreadDelegate::cacheCredentialsSlot(const QHttpNetworkRequest &reques
 #ifndef QT_NO_SSL
 void QHttpThreadDelegate::sslErrorsSlot(const QList<QSslError> &errors)
 {
+    if (!httpReply)
+        return;
+
     emit sslConfigurationChanged(httpReply->sslConfiguration());
 
     bool ignoreAll = false;
@@ -595,6 +608,9 @@ void QHttpThreadDelegate::sslErrorsSlot(const QList<QSslError> &errors)
 
 void QHttpThreadDelegate::synchronousAuthenticationRequiredSlot(const QHttpNetworkRequest &request, QAuthenticator *a)
 {
+    if (!httpReply)
+        return;
+
     Q_UNUSED(request);
 #ifdef QHTTPTHREADDELEGATE_DEBUG
     qDebug() << "QHttpThreadDelegate::synchronousAuthenticationRequiredSlot() thread=" << QThread::currentThreadId();
@@ -615,6 +631,9 @@ void QHttpThreadDelegate::synchronousAuthenticationRequiredSlot(const QHttpNetwo
 #ifndef QT_NO_NETWORKPROXY
 void  QHttpThreadDelegate::synchronousProxyAuthenticationRequiredSlot(const QNetworkProxy &p, QAuthenticator *a)
 {
+    if (!httpReply)
+        return;
+
 #ifdef QHTTPTHREADDELEGATE_DEBUG
     qDebug() << "QHttpThreadDelegate::synchronousProxyAuthenticationRequiredSlot() thread=" << QThread::currentThreadId();
 #endif