[iOS] QuickLook returns an invalid MIME type for some documents
authoraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 6 Aug 2014 17:23:04 +0000 (17:23 +0000)
committeraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 6 Aug 2014 17:23:04 +0000 (17:23 +0000)
https://bugs.webkit.org/show_bug.cgi?id=135651

Reviewed by David Kilzer.

In some cases QuickLook indicates a failure by returning a nil MIME type in -[QLPreviewConverter previewResponse]
rather than calling connection:didFailWithError:. Calling ResourceLoader::didReceiveResponse() with a response
containing a nil MIME type leads to a crash.

Stop loading the resource and display an error page if QuickLook cannot provide a MIME type for the converted response.

No new tests. QuickLook is not testable from WebKit.

* platform/network/ios/QuickLook.mm:
(-[WebResourceLoaderQuickLookDelegate _sendDidReceiveResponseIfNecessary]): Called ResourceLoader::didFail() if
MIME type was nil. Called ResourceLoader::didReceiveResponse() otherwise.
(-[WebResourceLoaderQuickLookDelegate connection:didReceiveDataArray:]): Called -_sendDidReceiveResponseIfNecessary.
(-[WebResourceLoaderQuickLookDelegate connection:didReceiveData:lengthReceived:]): Ditto.
(-[WebResourceLoaderQuickLookDelegate connection:didFailWithError:]): Ditto.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@172151 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/network/ios/QuickLook.mm

index a89b9f1..0d965bc 100644 (file)
@@ -1,3 +1,25 @@
+2014-08-06  Andy Estes  <aestes@apple.com>
+
+        [iOS] QuickLook returns an invalid MIME type for some documents
+        https://bugs.webkit.org/show_bug.cgi?id=135651
+
+        Reviewed by David Kilzer.
+
+        In some cases QuickLook indicates a failure by returning a nil MIME type in -[QLPreviewConverter previewResponse]
+        rather than calling connection:didFailWithError:. Calling ResourceLoader::didReceiveResponse() with a response
+        containing a nil MIME type leads to a crash.
+
+        Stop loading the resource and display an error page if QuickLook cannot provide a MIME type for the converted response.
+
+        No new tests. QuickLook is not testable from WebKit.
+
+        * platform/network/ios/QuickLook.mm:
+        (-[WebResourceLoaderQuickLookDelegate _sendDidReceiveResponseIfNecessary]): Called ResourceLoader::didFail() if
+        MIME type was nil. Called ResourceLoader::didReceiveResponse() otherwise.
+        (-[WebResourceLoaderQuickLookDelegate connection:didReceiveDataArray:]): Called -_sendDidReceiveResponseIfNecessary.
+        (-[WebResourceLoaderQuickLookDelegate connection:didReceiveData:lengthReceived:]): Ditto.
+        (-[WebResourceLoaderQuickLookDelegate connection:didFailWithError:]): Ditto.
+
 2014-08-06  Radu Stavila  <stavila@adobe.com>
 
         REGRESSION (r163382): Overflow hidden for inner elements breaks blurring
index d267aea..bf85ede 100644 (file)
@@ -324,6 +324,7 @@ const char* WebCore::QLPreviewProtocol()
 @interface WebResourceLoaderQuickLookDelegate : NSObject <NSURLConnectionDelegate> {
     RefPtr<ResourceLoader> _resourceLoader;
     BOOL _hasSentDidReceiveResponse;
+    BOOL _hasFailed;
 }
 @property (nonatomic) QuickLookHandle* quickLookHandle;
 @end
@@ -340,6 +341,24 @@ const char* WebCore::QLPreviewProtocol()
     return self;
 }
 
+- (void)_sendDidReceiveResponseIfNecessary
+{
+    if (_hasSentDidReceiveResponse || _hasFailed || !_quickLookHandle)
+        return;
+
+    // QuickLook might fail to convert a document without calling connection:didFailWithError: (see <rdar://problem/17927972>).
+    // A nil MIME type is an indication of such a failure, so stop loading the resource and ignore subsequent delegate messages.
+    NSURLResponse *previewResponse = _quickLookHandle->nsResponse();
+    if (![previewResponse MIMEType]) {
+        _hasFailed = YES;
+        _resourceLoader->didFail(_resourceLoader->cannotShowURLError());
+        return;
+    }
+
+    _hasSentDidReceiveResponse = YES;
+    _resourceLoader->didReceiveResponse(previewResponse);
+}
+
 #if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
 - (void)connection:(NSURLConnection *)connection didReceiveDataArray:(NSArray *)dataArray
 {
@@ -347,10 +366,9 @@ const char* WebCore::QLPreviewProtocol()
     if (!_resourceLoader)
         return;
 
-    if (!_hasSentDidReceiveResponse && _quickLookHandle) {
-        _hasSentDidReceiveResponse = YES;
-        _resourceLoader->didReceiveResponse(_quickLookHandle->nsResponse());
-    }
+    [self _sendDidReceiveResponseIfNecessary];
+    if (_hasFailed)
+        return;
 
     _resourceLoader->didReceiveDataArray(reinterpret_cast<CFArrayRef>(dataArray));
 }
@@ -362,10 +380,9 @@ const char* WebCore::QLPreviewProtocol()
     if (!_resourceLoader)
         return;
 
-    if (!_hasSentDidReceiveResponse && _quickLookHandle) {
-        _hasSentDidReceiveResponse = YES;
-        _resourceLoader->didReceiveResponse(_quickLookHandle->nsResponse());
-    }
+    [self _sendDidReceiveResponseIfNecessary];
+    if (_hasFailed)
+        return;
 
     // QuickLook code sends us a nil data at times. The check below is the same as the one in
     // ResourceHandleMac.cpp added for a different bug.
@@ -388,10 +405,9 @@ const char* WebCore::QLPreviewProtocol()
 {
     UNUSED_PARAM(connection);
 
-    if (!_hasSentDidReceiveResponse && _quickLookHandle) {
-        _hasSentDidReceiveResponse = YES;
-        _resourceLoader->didReceiveResponse(_quickLookHandle->nsResponse());
-    }
+    [self _sendDidReceiveResponseIfNecessary];
+    if (_hasFailed)
+        return;
 
     _resourceLoader->didFail(ResourceError(error));
 }