PNG mask images are loaded with Accept:image/svg+xml
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 1 Jul 2015 17:22:27 +0000 (17:22 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 1 Jul 2015 17:22:27 +0000 (17:22 +0000)
https://bugs.webkit.org/show_bug.cgi?id=146509
Source/WebCore:

rdar://problem/21584740

Reviewed by Simon Fraser.

For some strange reason MaskImageOperation code loads all mask images, including non-SVG ones
using CachedSVGDocument. Resulting bad accept header may cause server to reject the request.

This is far from ideal but as a quick fix we can override the accept header for mask images to
allow any image type.

Test: http/tests/misc/mask-image-accept.html

* loader/cache/CachedResourceLoader.cpp:
(WebCore::CachedResourceLoader::requestResource):
* loader/cache/CachedResourceRequest.h:
(WebCore::CachedResourceRequest::acceptOverride):
(WebCore::CachedResourceRequest::setAcceptOverride):
* loader/cache/CachedSVGDocumentReference.cpp:
(WebCore::CachedSVGDocumentReference::load):
* loader/cache/CachedSVGDocumentReference.h:
(WebCore::CachedSVGDocumentReference::loadRequested):
(WebCore::CachedSVGDocumentReference::setAcceptsAnyImageType):
(WebCore::CachedSVGDocumentReference::document):
* platform/graphics/MaskImageOperation.cpp:
(WebCore::MaskImageOperation::ensureCachedSVGDocumentReference):

LayoutTests:

Reviewed by Simon Fraser.

* http/tests/misc/mask-image-accept-expected.html: Added.
* http/tests/misc/mask-image-accept.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/http/tests/misc/mask-image-accept-expected.html [new file with mode: 0644]
LayoutTests/http/tests/misc/mask-image-accept.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/loader/cache/CachedResourceLoader.cpp
Source/WebCore/loader/cache/CachedResourceRequest.h
Source/WebCore/loader/cache/CachedSVGDocumentReference.cpp
Source/WebCore/loader/cache/CachedSVGDocumentReference.h
Source/WebCore/platform/graphics/MaskImageOperation.cpp

index d9d83b4..b557923 100644 (file)
@@ -1,3 +1,13 @@
+2015-07-01  Antti Koivisto  <antti@apple.com>
+
+        PNG mask images are loaded with Accept:image/svg+xml
+        https://bugs.webkit.org/show_bug.cgi?id=146509
+
+        Reviewed by Simon Fraser.
+
+        * http/tests/misc/mask-image-accept-expected.html: Added.
+        * http/tests/misc/mask-image-accept.html: Added.
+
 2015-07-01  Jer Noble  <jer.noble@apple.com>
 
         [MSE] Failures on W3C media-source tests regarding MIME types
diff --git a/LayoutTests/http/tests/misc/mask-image-accept-expected.html b/LayoutTests/http/tests/misc/mask-image-accept-expected.html
new file mode 100644 (file)
index 0000000..a9547ee
--- /dev/null
@@ -0,0 +1,10 @@
+<html>
+<head>
+<style>
+#test { width:100px; height:100px; background-color: green;}
+</style>
+</head>
+<body>
+<div id="test"></div>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/misc/mask-image-accept.html b/LayoutTests/http/tests/misc/mask-image-accept.html
new file mode 100644 (file)
index 0000000..6215c78
--- /dev/null
@@ -0,0 +1,10 @@
+<html>
+<head>
+<style>
+#test { -webkit-mask-image: url(resources/image-checks-for-accept.php); width:100px; height:100px; background-color: green;}
+</style>
+</head>
+<body>
+<div id="test"></div>
+</body>
+</html>
index 79c1a01..2d11a8e 100644 (file)
@@ -1,3 +1,33 @@
+2015-07-01  Antti Koivisto  <antti@apple.com>
+
+        PNG mask images are loaded with Accept:image/svg+xml
+        https://bugs.webkit.org/show_bug.cgi?id=146509
+        rdar://problem/21584740
+
+        Reviewed by Simon Fraser.
+
+        For some strange reason MaskImageOperation code loads all mask images, including non-SVG ones
+        using CachedSVGDocument. Resulting bad accept header may cause server to reject the request.
+
+        This is far from ideal but as a quick fix we can override the accept header for mask images to
+        allow any image type.
+
+        Test: http/tests/misc/mask-image-accept.html
+
+        * loader/cache/CachedResourceLoader.cpp:
+        (WebCore::CachedResourceLoader::requestResource):
+        * loader/cache/CachedResourceRequest.h:
+        (WebCore::CachedResourceRequest::acceptOverride):
+        (WebCore::CachedResourceRequest::setAcceptOverride):
+        * loader/cache/CachedSVGDocumentReference.cpp:
+        (WebCore::CachedSVGDocumentReference::load):
+        * loader/cache/CachedSVGDocumentReference.h:
+        (WebCore::CachedSVGDocumentReference::loadRequested):
+        (WebCore::CachedSVGDocumentReference::setAcceptsAnyImageType):
+        (WebCore::CachedSVGDocumentReference::document):
+        * platform/graphics/MaskImageOperation.cpp:
+        (WebCore::MaskImageOperation::ensureCachedSVGDocumentReference):
+
 2015-07-01  Jer Noble  <jer.noble@apple.com>
 
         [MSE] Failures on W3C media-source tests regarding MIME types
index 6c30d74..ad17373 100644 (file)
@@ -565,6 +565,9 @@ CachedResourceHandle<CachedResource> CachedResourceLoader::requestResource(Cache
         resource->setLoadPriority(request.priority());
 
     if ((policy != Use || resource->stillNeedsLoad()) && CachedResourceRequest::NoDefer == request.defer()) {
+        if (request.acceptOverride())
+            resource->setAccept(request.acceptOverride().value());
+
         resource->load(*this, request.options());
 
         // We don't support immediate loads, but we do support immediate failure.
index 41dcddc..6f46b67 100644 (file)
@@ -53,12 +53,14 @@ public:
     const ResourceLoaderOptions& options() const { return m_options; }
     void setOptions(const ResourceLoaderOptions& options) { m_options = options; }
     const Optional<ResourceLoadPriority>& priority() const { return m_priority; }
+    const Optional<String>& acceptOverride() const { return m_acceptOverride; }
     bool forPreload() const { return m_forPreload; }
     void setForPreload(bool forPreload) { m_forPreload = forPreload; }
     DeferOption defer() const { return m_defer; }
     void setDefer(DeferOption defer) { m_defer = defer; }
     void setInitiator(PassRefPtr<Element>);
     void setInitiator(const AtomicString& name);
+    void setAcceptOverride(const String& accept) { m_acceptOverride = accept; }
     const AtomicString& initiatorName() const;
 
     void setInitiator(DocumentLoader&);
@@ -69,6 +71,7 @@ private:
     String m_charset;
     ResourceLoaderOptions m_options;
     Optional<ResourceLoadPriority> m_priority;
+    Optional<String> m_acceptOverride;
     bool m_forPreload;
     DeferOption m_defer;
     RefPtr<Element> m_initiatorElement;
index c627f4e..681b9fa 100644 (file)
@@ -60,6 +60,8 @@ void CachedSVGDocumentReference::load(CachedResourceLoader& loader)
 
     CachedResourceRequest request(ResourceRequest(loader.document()->completeURL(m_url)));
     request.setInitiator(cachedResourceRequestInitiators().css);
+    if (m_acceptsAnyImageType)
+        request.setAcceptOverride("image/*");
     m_document = loader.requestSVGDocument(request);
     if (m_document) {
         m_document->setCanReuse(m_canReuseResource);
index 5e032ad..f1c54f4 100644 (file)
@@ -43,6 +43,7 @@ public:
 
     void load(CachedResourceLoader&);
     bool loadRequested() const { return m_loadRequested; }
+    void setAcceptsAnyImageType() { m_acceptsAnyImageType = true; }
 
     CachedSVGDocument* document() { return m_document.get(); }
 
@@ -52,6 +53,7 @@ private:
     bool m_loadRequested;
     CachedSVGDocumentClient* m_additionalDocumentClient;
     bool m_canReuseResource;
+    bool m_acceptsAnyImageType { false };
 };
 
 };
index 46142e3..e8f7230 100644 (file)
@@ -193,8 +193,12 @@ CachedSVGDocumentReference* MaskImageOperation::ensureCachedSVGDocumentReference
     if (image())
         return nullptr;
 
-    if (!m_cachedSVGDocumentReference.get())
+    if (!m_cachedSVGDocumentReference.get()) {
         m_cachedSVGDocumentReference = std::make_unique<CachedSVGDocumentReference>(m_url, this, false);
+        // FIXME: For some strange reason we load all mask resources using CachedSVGDocument.
+        //        This requires overriding SVG mime type in Accept header or server may reject the request.
+        m_cachedSVGDocumentReference->setAcceptsAnyImageType();
+    }
     return m_cachedSVGDocumentReference.get();
 }
 
@@ -219,9 +223,10 @@ void MaskImageOperation::notifyFinished(CachedResource* resource)
             }
         }
     }
-    
+
     // If no valid mask was found, this is not a valid SVG document or it specified an invalid fragment identifier.
     // Fallback to the normal way of loading the document in an Image object.
+    // FIXME: This is silly.
     if (!validMaskFound) {
         // Get the resource loader, acquire the resource buffer and load it into an image.
         ASSERT(cachedSVGDocument->loader());