Title: [253474] trunk
Revision
253474
Author
[email protected]
Date
2019-12-13 08:22:44 -0800 (Fri, 13 Dec 2019)

Log Message

Implement OffscreenCanvas.convertToBlob
https://bugs.webkit.org/show_bug.cgi?id=202573

Patch by Chris Lord <[email protected]> on 2019-12-13
Reviewed by Darin Adler.

LayoutTests/imported/w3c:

Update with fixed worker tests and SecurityError checks. See wpe
issues #20694 and #20698.

* web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob-expected.txt:
* web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob.html:
* web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob.w-expected.txt:
* web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob.w.html:

Source/WebCore:

Implement OffscreenCanvas.convertToBlob. This also involves making
isSupportedImageMIMETypeForEncoding safe to use off the main thread,
and implementing OffscreenCanvas.securityOrigin.

No new tests, these changes fix existing tests.

* html/OffscreenCanvas.cpp:
(WebCore::toEncodingMimeType):
(WebCore::qualityFromDouble):
(WebCore::OffscreenCanvas::convertToBlob):
(WebCore::OffscreenCanvas::securityOrigin const):
* html/OffscreenCanvas.h:
* html/OffscreenCanvas.idl:
* platform/MIMETypeRegistry.cpp:
(WebCore::MIMETypeRegistry::createMIMETypeRegistryThreadGlobalData):
(WebCore::MIMETypeRegistry::isSupportedImageMIMETypeForEncoding):
* platform/MIMETypeRegistry.h:
(WebCore::MIMETypeRegistryThreadGlobalData::MIMETypeRegistryThreadGlobalData):
(WebCore::MIMETypeRegistryThreadGlobalData::supportedImageMIMETypesForEncoding const):
* platform/ThreadGlobalData.cpp:
(WebCore::ThreadGlobalData::mimeTypeRegistryThreadGlobalData):
* platform/ThreadGlobalData.h:
* workers/WorkerGlobalScope.h:

Modified Paths

Diff

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (253473 => 253474)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2019-12-13 16:19:08 UTC (rev 253473)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2019-12-13 16:22:44 UTC (rev 253474)
@@ -1,3 +1,18 @@
+2019-12-13  Chris Lord  <[email protected]>
+
+        Implement OffscreenCanvas.convertToBlob
+        https://bugs.webkit.org/show_bug.cgi?id=202573
+
+        Reviewed by Darin Adler.
+
+        Update with fixed worker tests and SecurityError checks. See wpe
+        issues #20694 and #20698.
+
+        * web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob-expected.txt:
+        * web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob.html:
+        * web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob.w-expected.txt:
+        * web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob.w.html:
+
 2019-12-12  Chris Dumez  <[email protected]>
 
         Re-sync service-workers web-platform-tests from upstream

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob-expected.txt (253473 => 253474)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob-expected.txt	2019-12-13 16:19:08 UTC (rev 253473)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob-expected.txt	2019-12-13 16:22:44 UTC (rev 253474)
@@ -1,8 +1,9 @@
 
-FAIL Test that convertToBlob with default type produces correct result offscreenCanvas.convertToBlob is not a function. (In 'offscreenCanvas.convertToBlob()', 'offscreenCanvas.convertToBlob' is undefined)
-FAIL Test that convertToBlob with png produces correct result offscreenCanvas.convertToBlob is not a function. (In 'offscreenCanvas.convertToBlob({type: typeVal})', 'offscreenCanvas.convertToBlob' is undefined)
-FAIL Test that convertToBlob with jpge produces correct result offscreenCanvas.convertToBlob is not a function. (In 'offscreenCanvas.convertToBlob({type: typeVal})', 'offscreenCanvas.convertToBlob' is undefined)
-FAIL Test that convertToBlob with webp produces correct result offscreenCanvas.convertToBlob is not a function. (In 'offscreenCanvas.convertToBlob({type: typeVal})', 'offscreenCanvas.convertToBlob' is undefined)
+PASS Test that convertToBlob with default type produces correct result 
+PASS Test that convertToBlob with png produces correct result 
+PASS Test that convertToBlob with jpge produces correct result 
+PASS Test that convertToBlob with webp produces correct result 
 FAIL Test that call convertToBlob on a detached OffscreenCanvas throws exception The object can not be cloned.
-FAIL Test that call convertToBlob on a OffscreenCanvas with size 0 throws exception offscreenCanvas.convertToBlob is not a function. (In 'offscreenCanvas.convertToBlob()', 'offscreenCanvas.convertToBlob' is undefined)
+PASS Test that call convertToBlob on a OffscreenCanvas with size 0 throws exception 
+PASS Test that call convertToBlob on a OffscreenCanvas with tainted origin throws exception 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob.html (253473 => 253474)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob.html	2019-12-13 16:19:08 UTC (rev 253473)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob.html	2019-12-13 16:22:44 UTC (rev 253474)
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <script src=""
 <script src=""
-<script src=""
+<script src=""
 <link rel="help" href=""
 <script id="myWorker" type="text/worker">
 self._onmessage_ = function(e) {
@@ -144,5 +144,22 @@
     }));
 }, "Test that call convertToBlob on a OffscreenCanvas with size 0 throws exception");
 
+async_test(function(t) {
+    var img = new Image();
+    img.src = ""
+    img.crossOrigin = "anonymous";
+    img._onload_ = t.step_func_done(() => {
+        var offscreenCanvas = new OffscreenCanvas(10, 10);
+        var ctx = offscreenCanvas.getContext("2d");
+        ctx.drawImage(img, 0, 0);
+        offscreenCanvas.convertToBlob().then(t.step_func_done(function() {
+            assert_false("convertToBlob didn't throw, but should");
+        }), t.step_func_done(function(e) {
+            assert_true(e instanceof DOMException);
+            assert_equals(e.name, "SecurityError");
+        }));
+    });
+}, "Test that call convertToBlob on a OffscreenCanvas with tainted origin throws exception");
+
 </script>
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob.w-expected.txt (253473 => 253474)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob.w-expected.txt	2019-12-13 16:19:08 UTC (rev 253473)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob.w-expected.txt	2019-12-13 16:22:44 UTC (rev 253474)
@@ -1,18 +1,19 @@
 
-Harness Error (FAIL), message = TypeError: offscreenCanvas.convertToBlob is not a function. (In 'offscreenCanvas.convertToBlob({type: typeVal, quality: qualityVal})', 'offscreenCanvas.convertToBlob' is undefined)
+Harness Error (FAIL), message = DataCloneError: The object can not be cloned.
 
-FAIL Test that convertToBlob with default arguments produces correct result in a worker assert_unreached: error Reached unreachable code
-FAIL Test that convertToBlob with default type/1.0 quality produces correct result in a worker assert_unreached: error Reached unreachable code
-FAIL Test that convertToBlob with default type/0.2 quality produces correct result in a worker assert_unreached: error Reached unreachable code
-FAIL Test that convertToBlob with png/default quality produces correct result in a worker assert_unreached: error Reached unreachable code
-FAIL Test that convertToBlob with png/1.0 quality produces correct result in a worker assert_unreached: error Reached unreachable code
-FAIL Test that convertToBlob with png/0.2 quality produces correct result in a worker assert_unreached: error Reached unreachable code
-FAIL Test that convertToBlob with jpeg/default quality produces correct result in a worker assert_unreached: error Reached unreachable code
-FAIL Test that convertToBlob with jpeg/1.0 quality produces correct result in a worker assert_unreached: error Reached unreachable code
-FAIL Test that convertToBlob with jpeg/0.2 quality produces correct result in a worker assert_unreached: error Reached unreachable code
-FAIL Test that convertToBlob with webp/default quality produces correct result in a worker assert_unreached: error Reached unreachable code
-FAIL Test that convertToBlob with webp/1.0 quality produces correct result in a worker assert_unreached: error Reached unreachable code
-FAIL Test that convertToBlob with webp/0.2 quality produces correct result in a worker assert_unreached: error Reached unreachable code
+PASS Test that convertToBlob with default arguments produces correct result in a worker 
+PASS Test that convertToBlob with default type/1.0 quality produces correct result in a worker 
+PASS Test that convertToBlob with default type/0.2 quality produces correct result in a worker 
+PASS Test that convertToBlob with png/default quality produces correct result in a worker 
+PASS Test that convertToBlob with png/1.0 quality produces correct result in a worker 
+PASS Test that convertToBlob with png/0.2 quality produces correct result in a worker 
+PASS Test that convertToBlob with jpeg/default quality produces correct result in a worker 
+PASS Test that convertToBlob with jpeg/1.0 quality produces correct result in a worker 
+PASS Test that convertToBlob with jpeg/0.2 quality produces correct result in a worker 
+PASS Test that convertToBlob with webp/default quality produces correct result in a worker 
+PASS Test that convertToBlob with webp/1.0 quality produces correct result in a worker 
+PASS Test that convertToBlob with webp/0.2 quality produces correct result in a worker 
 FAIL Test that call convertToBlob on a detached OffscreenCanvas throws exception in a worker assert_unreached: error Reached unreachable code
-FAIL Test that call convertToBlob on a OffscreenCanvas with size 0 throws exception in a worker assert_unreached: error Reached unreachable code
+PASS Test that call convertToBlob on a OffscreenCanvas with size 0 throws exception in a worker 
+PASS Test that call convertToBlob on a OffscreenCanvas with tainted origin throws exception in a worker 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob.w.html (253473 => 253474)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob.w.html	2019-12-13 16:19:08 UTC (rev 253473)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob.w.html	2019-12-13 16:22:44 UTC (rev 253474)
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <script src=""
 <script src=""
-<script src=""
+<script src=""
 <link rel="help" href=""
 <script id="myWorker" type="text/worker">
 function drawCanvas(ctx)
@@ -40,12 +40,9 @@
     var offscreenCanvas = new OffscreenCanvas(10, 10);
     self.postMessage({offscreenCanvas}, [offscreenCanvas]);
     offscreenCanvas.convertToBlob().then(function() {
-        return false;
+        self.postMessage(false);
     }, function(e) {
-        if (e instanceof DOMException && e.name == "InvalidStateError")
-            return true;
-        else
-            return false;
+        self.postMessage(e instanceof DOMException && e.name == "InvalidStateError");
     });
 }
 
@@ -53,16 +50,30 @@
 {
     var offscreenCanvas = new OffscreenCanvas(0, 0);
     offscreenCanvas.convertToBlob().then(function() {
-        return false;
+        self.postMessage(false);
     }, function(e) {
-        if (e instanceof DOMException && e.name == "IndexSizeError")
-            return true;
-        else
-            return false;
+        self.postMessage(e instanceof DOMException && e.name == "IndexSizeError");
     });
 }
 
+function testConvertToBlobException3(bitmap)
+{
+    var offscreenCanvas = new OffscreenCanvas(10, 10);
+    var ctx = offscreenCanvas.getContext("2d");
+    ctx.drawImage(bitmap, 0, 0);
+    offscreenCanvas.convertToBlob().then(function() {
+        self.postMessage(false);
+    }, function(e) {
+        self.postMessage(e instanceof DOMException && e.name == "SecurityError");
+    });
+}
+
 self._onmessage_ = function(e) {
+    if (e.data instanceof ImageBitmap) {
+        testConvertToBlobException3(e.data);
+        return;
+    }
+
     switch(e.data) {
         case 'test1':
             testConvertToBlob("empty", "empty");
@@ -101,10 +112,10 @@
             testConvertToBlob("image/webp", 0.2);
             break;
         case 'test13':
-            self.postMessage(testConvertToBlobException1());
+            testConvertToBlobException1();
             break;
         case 'test14':
-            self.postMessage(testConvertToBlobException2());
+            testConvertToBlobException2();
             break;
     }
 };
@@ -289,8 +300,8 @@
 async_test(function(t) {
     var worker = makeWorker(t);
     worker.addEventListener('message', t.step_func_done(function(msg) {
-        if (msg.data == true || msg.data == false)
-            assert_true(msg.data);
+        assert_true(msg.data);
+        t.done();
     }));
     worker.postMessage('test13');
 }, "Test that call convertToBlob on a detached OffscreenCanvas throws exception in a worker");
@@ -298,11 +309,27 @@
 async_test(function(t) {
     var worker = makeWorker(t);
     worker.addEventListener('message', t.step_func_done(function(msg) {
-        if (msg.data == true || msg.data == false)
-            assert_true(msg.data);
+        assert_true(msg.data);
+        t.done();
     }));
     worker.postMessage('test14');
 }, "Test that call convertToBlob on a OffscreenCanvas with size 0 throws exception in a worker");
 
+async_test(function(t) {
+    var img = new Image();
+    img.src = ""
+    img.crossOrigin = "anonymous";
+    img._onload_ = t.step_func_done(() => {
+        createImageBitmap(img).then(t.step_func_done(bitmap => {
+            var worker = makeWorker(t);
+            worker.addEventListener('message', t.step_func_done(function(msg) {
+                assert_true(msg.data);
+                t.done();
+            }));
+            worker.postMessage(bitmap);
+        }));
+    });
+}, "Test that call convertToBlob on a OffscreenCanvas with tainted origin throws exception in a worker");
+
 </script>
 

Modified: trunk/Source/WebCore/ChangeLog (253473 => 253474)


--- trunk/Source/WebCore/ChangeLog	2019-12-13 16:19:08 UTC (rev 253473)
+++ trunk/Source/WebCore/ChangeLog	2019-12-13 16:22:44 UTC (rev 253474)
@@ -1,3 +1,34 @@
+2019-12-13  Chris Lord  <[email protected]>
+
+        Implement OffscreenCanvas.convertToBlob
+        https://bugs.webkit.org/show_bug.cgi?id=202573
+
+        Reviewed by Darin Adler.
+
+        Implement OffscreenCanvas.convertToBlob. This also involves making
+        isSupportedImageMIMETypeForEncoding safe to use off the main thread,
+        and implementing OffscreenCanvas.securityOrigin.
+
+        No new tests, these changes fix existing tests.
+
+        * html/OffscreenCanvas.cpp:
+        (WebCore::toEncodingMimeType):
+        (WebCore::qualityFromDouble):
+        (WebCore::OffscreenCanvas::convertToBlob):
+        (WebCore::OffscreenCanvas::securityOrigin const):
+        * html/OffscreenCanvas.h:
+        * html/OffscreenCanvas.idl:
+        * platform/MIMETypeRegistry.cpp:
+        (WebCore::MIMETypeRegistry::createMIMETypeRegistryThreadGlobalData):
+        (WebCore::MIMETypeRegistry::isSupportedImageMIMETypeForEncoding):
+        * platform/MIMETypeRegistry.h:
+        (WebCore::MIMETypeRegistryThreadGlobalData::MIMETypeRegistryThreadGlobalData):
+        (WebCore::MIMETypeRegistryThreadGlobalData::supportedImageMIMETypesForEncoding const):
+        * platform/ThreadGlobalData.cpp:
+        (WebCore::ThreadGlobalData::mimeTypeRegistryThreadGlobalData):
+        * platform/ThreadGlobalData.h:
+        * workers/WorkerGlobalScope.h:
+
 2019-12-13  youenn fablet  <[email protected]>
 
         Make DOMCacheStorage::retrieveCaches take a CompletionHandler

Modified: trunk/Source/WebCore/html/OffscreenCanvas.cpp (253473 => 253474)


--- trunk/Source/WebCore/html/OffscreenCanvas.cpp	2019-12-13 16:19:08 UTC (rev 253473)
+++ trunk/Source/WebCore/html/OffscreenCanvas.cpp	2019-12-13 16:22:44 UTC (rev 253474)
@@ -31,7 +31,9 @@
 #include "CSSValuePool.h"
 #include "CanvasRenderingContext.h"
 #include "ImageBitmap.h"
+#include "JSBlob.h"
 #include "JSDOMPromiseDeferred.h"
+#include "MIMETypeRegistry.h"
 #include "OffscreenCanvasRenderingContext2D.h"
 #include "WebGLRenderingContext.h"
 #include "WorkerGlobalScope.h"
@@ -165,11 +167,65 @@
     return Exception { NotSupportedError };
 }
 
+static String toEncodingMimeType(const String& mimeType)
+{
+    if (!MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType))
+        return "image/png"_s;
+    return mimeType.convertToASCIILowercase();
+}
+
+static Optional<double> qualityFromDouble(double qualityNumber)
+{
+    if (!(qualityNumber >= 0 && qualityNumber <= 1))
+        return WTF::nullopt;
+
+    return qualityNumber;
+}
+
+void OffscreenCanvas::convertToBlob(ImageEncodeOptions&& options, Ref<DeferredPromise>&& promise)
+{
+    if (!originClean()) {
+        promise->reject(SecurityError);
+        return;
+    }
+    if (size().isEmpty()) {
+        promise->reject(IndexSizeError);
+        return;
+    }
+    if (!buffer()) {
+        promise->reject(InvalidStateError);
+        return;
+    }
+
+    makeRenderingResultsAvailable();
+
+    auto encodingMIMEType = toEncodingMimeType(options.type);
+    auto quality = qualityFromDouble(options.quality);
+
+    Vector<uint8_t> blobData = buffer()->toData(encodingMIMEType, quality);
+    if (blobData.isEmpty()) {
+        promise->reject(EncodingError);
+        return;
+    }
+
+    Ref<Blob> blob = Blob::create(WTFMove(blobData), encodingMIMEType);
+    promise->resolveWithNewlyCreated<IDLInterface<Blob>>(WTFMove(blob));
+}
+
 void OffscreenCanvas::didDraw(const FloatRect& rect)
 {
     notifyObserversCanvasChanged(rect);
 }
 
+SecurityOrigin* OffscreenCanvas::securityOrigin() const
+{
+    auto& context = *canvasBaseScriptExecutionContext();
+    if (is<WorkerGlobalScope>(context))
+        return &downcast<WorkerGlobalScope>(context).topOrigin();
+
+    return &downcast<Document>(context).securityOrigin();
+}
+
 CSSValuePool& OffscreenCanvas::cssValuePool()
 {
     auto* context = canvasBaseScriptExecutionContext();

Modified: trunk/Source/WebCore/html/OffscreenCanvas.h (253473 => 253474)


--- trunk/Source/WebCore/html/OffscreenCanvas.h	2019-12-13 16:19:08 UTC (rev 253473)
+++ trunk/Source/WebCore/html/OffscreenCanvas.h	2019-12-13 16:22:44 UTC (rev 253474)
@@ -43,6 +43,7 @@
 
 class CanvasRenderingContext;
 class CSSValuePool;
+class DeferredPromise;
 class ImageBitmap;
 class OffscreenCanvasRenderingContext2D;
 class WebGLRenderingContext;
@@ -79,7 +80,7 @@
     ExceptionOr<OffscreenRenderingContext> getContext(JSC::JSGlobalObject&, RenderingContextType, Vector<JSC::Strong<JSC::Unknown>>&& arguments);
 #endif
     ExceptionOr<RefPtr<ImageBitmap>> transferToImageBitmap();
-    // void convertToBlob(ImageEncodeOptions options);
+    void convertToBlob(ImageEncodeOptions&&, Ref<DeferredPromise>&&);
 
     void didDraw(const FloatRect&) final;
 
@@ -86,6 +87,7 @@
     Image* copiedImage() const final { return nullptr; }
     bool hasCreatedImageBuffer() const final { return m_hasCreatedImageBuffer; }
 
+    SecurityOrigin* securityOrigin() const final;
     CSSValuePool& cssValuePool();
 
     using RefCounted::ref;

Modified: trunk/Source/WebCore/html/OffscreenCanvas.idl (253473 => 253474)


--- trunk/Source/WebCore/html/OffscreenCanvas.idl	2019-12-13 16:19:08 UTC (rev 253473)
+++ trunk/Source/WebCore/html/OffscreenCanvas.idl	2019-12-13 16:22:44 UTC (rev 253474)
@@ -54,6 +54,6 @@
 
     [CallWith=GlobalObject, MayThrowException] OffscreenRenderingContext? getContext(OffscreenRenderingContextType contextType, any... arguments);
     [MayThrowException] ImageBitmap transferToImageBitmap();
-    // Promise<Blob> convertToBlob(optional ImageEncodeOptions options);
+    Promise<Blob> convertToBlob(optional ImageEncodeOptions options);
 
 };

Modified: trunk/Source/WebCore/platform/MIMETypeRegistry.cpp (253473 => 253474)


--- trunk/Source/WebCore/platform/MIMETypeRegistry.cpp	2019-12-13 16:19:08 UTC (rev 253473)
+++ trunk/Source/WebCore/platform/MIMETypeRegistry.cpp	2019-12-13 16:22:44 UTC (rev 253474)
@@ -28,6 +28,7 @@
 #include "MIMETypeRegistry.h"
 
 #include "MediaPlayer.h"
+#include "ThreadGlobalData.h"
 #include <wtf/HashMap.h>
 #include <wtf/MainThread.h>
 #include <wtf/NeverDestroyed.h>
@@ -170,43 +171,6 @@
     return additionalSupportedImageMIMETypes;
 }
 
-static const HashSet<String, ASCIICaseInsensitiveHash>& supportedImageMIMETypesForEncoding()
-{
-#if PLATFORM(COCOA)
-    static const auto supportedImageMIMETypesForEncoding = makeNeverDestroyed([] {
-        RetainPtr<CFArrayRef> supportedTypes = adoptCF(CGImageDestinationCopyTypeIdentifiers());
-        HashSet<String, ASCIICaseInsensitiveHash> supportedImageMIMETypesForEncoding;
-        CFIndex count = CFArrayGetCount(supportedTypes.get());
-        for (CFIndex i = 0; i < count; i++) {
-            CFStringRef supportedType = reinterpret_cast<CFStringRef>(CFArrayGetValueAtIndex(supportedTypes.get(), i));
-            String mimeType = MIMETypeForImageType(supportedType);
-            if (!mimeType.isEmpty())
-                supportedImageMIMETypesForEncoding.add(mimeType);
-        }
-        return supportedImageMIMETypesForEncoding;
-    }());
-#else
-    static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> supportedImageMIMETypesForEncoding =std::initializer_list<String> {
-#if USE(CG) || USE(DIRECT2D)
-        // FIXME: Add Windows support for all the supported UTI's when a way to convert from MIMEType to UTI reliably is found.
-        // For now, only support PNG, JPEG and GIF. See <rdar://problem/6095286>.
-        "image/png"_s,
-        "image/jpeg"_s,
-        "image/gif"_s,
-#elif PLATFORM(GTK)
-        "image/png"_s,
-        "image/jpeg"_s,
-        "image/tiff"_s,
-        "image/bmp"_s,
-        "image/ico"_s,
-#elif USE(CAIRO)
-        "image/png"_s,
-#endif
-    };
-#endif
-    return supportedImageMIMETypesForEncoding;
-}
-
 static const HashSet<String, ASCIICaseInsensitiveHash>& supportedJavaScriptMIMETypes()
 {
     static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> supportedJavaScriptMIMETypes = std::initializer_list<String> {
@@ -474,13 +438,45 @@
     return false;
 }
 
+std::unique_ptr<MIMETypeRegistryThreadGlobalData> MIMETypeRegistry::createMIMETypeRegistryThreadGlobalData()
+{
+#if PLATFORM(COCOA)
+    RetainPtr<CFArrayRef> supportedTypes = adoptCF(CGImageDestinationCopyTypeIdentifiers());
+    HashSet<String, ASCIICaseInsensitiveHash> supportedImageMIMETypesForEncoding;
+    CFIndex count = CFArrayGetCount(supportedTypes.get());
+    for (CFIndex i = 0; i < count; i++) {
+        CFStringRef supportedType = reinterpret_cast<CFStringRef>(CFArrayGetValueAtIndex(supportedTypes.get(), i));
+        String mimeType = MIMETypeForImageType(supportedType);
+        if (!mimeType.isEmpty())
+            supportedImageMIMETypesForEncoding.add(mimeType);
+    }
+#else
+    HashSet<String, ASCIICaseInsensitiveHash> supportedImageMIMETypesForEncoding = std::initializer_list<String> {
+#if USE(CG) || USE(DIRECT2D)
+        // FIXME: Add Windows support for all the supported UTI's when a way to convert from MIMEType to UTI reliably is found.
+        // For now, only support PNG, JPEG and GIF. See <rdar://problem/6095286>.
+        "image/png"_s,
+        "image/jpeg"_s,
+        "image/gif"_s,
+#elif PLATFORM(GTK)
+        "image/png"_s,
+        "image/jpeg"_s,
+        "image/tiff"_s,
+        "image/bmp"_s,
+        "image/ico"_s,
+#elif USE(CAIRO)
+        "image/png"_s,
+#endif
+    };
+#endif
+    return makeUnique<MIMETypeRegistryThreadGlobalData>(WTFMove(supportedImageMIMETypesForEncoding));
+}
+
 bool MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(const String& mimeType)
 {
-    ASSERT(isMainThread());
-
     if (mimeType.isEmpty())
         return false;
-    return supportedImageMIMETypesForEncoding().contains(mimeType);
+    return threadGlobalData().mimeTypeRegistryThreadGlobalData().supportedImageMIMETypesForEncoding().contains(mimeType);
 }
 
 bool MIMETypeRegistry::isSupportedJavaScriptMIMEType(const String& mimeType)

Modified: trunk/Source/WebCore/platform/MIMETypeRegistry.h (253473 => 253474)


--- trunk/Source/WebCore/platform/MIMETypeRegistry.h	2019-12-13 16:19:08 UTC (rev 253473)
+++ trunk/Source/WebCore/platform/MIMETypeRegistry.h	2019-12-13 16:22:44 UTC (rev 253474)
@@ -31,6 +31,20 @@
 
 namespace WebCore {
 
+struct MIMETypeRegistryThreadGlobalData {
+    WTF_MAKE_NONCOPYABLE(MIMETypeRegistryThreadGlobalData);
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    MIMETypeRegistryThreadGlobalData(HashSet<String, ASCIICaseInsensitiveHash>&& supportedImageMIMETypesForEncoding)
+        : m_supportedImageMIMETypesForEncoding(supportedImageMIMETypesForEncoding)
+    { }
+
+    const HashSet<String, ASCIICaseInsensitiveHash>& supportedImageMIMETypesForEncoding() const { return m_supportedImageMIMETypesForEncoding; }
+
+private:
+    HashSet<String, ASCIICaseInsensitiveHash> m_supportedImageMIMETypesForEncoding;
+};
+
 class MIMETypeRegistry {
 public:
     WEBCORE_EXPORT static String getMIMETypeForExtension(const String& extension);
@@ -43,6 +57,8 @@
 
     static String getMIMETypeForPath(const String& path);
 
+    static std::unique_ptr<MIMETypeRegistryThreadGlobalData> createMIMETypeRegistryThreadGlobalData();
+
     // Check to see if a MIME type is suitable for being loaded inline as an
     // image (e.g., <img> tags).
     WEBCORE_EXPORT static bool isSupportedImageMIMEType(const String& mimeType);

Modified: trunk/Source/WebCore/platform/ThreadGlobalData.cpp (253473 => 253474)


--- trunk/Source/WebCore/platform/ThreadGlobalData.cpp	2019-12-13 16:19:08 UTC (rev 253473)
+++ trunk/Source/WebCore/platform/ThreadGlobalData.cpp	2019-12-13 16:22:44 UTC (rev 253474)
@@ -29,6 +29,7 @@
 
 #include "CachedResourceRequestInitiators.h"
 #include "EventNames.h"
+#include "MIMETypeRegistry.h"
 #include "QualifiedNameCache.h"
 #include "TextCodecICU.h"
 #include "ThreadTimers.h"
@@ -117,4 +118,11 @@
 
 #endif
 
+const MIMETypeRegistryThreadGlobalData& ThreadGlobalData::mimeTypeRegistryThreadGlobalData()
+{
+    if (UNLIKELY(!m_MIMETypeRegistryThreadGlobalData))
+        m_MIMETypeRegistryThreadGlobalData = MIMETypeRegistry::createMIMETypeRegistryThreadGlobalData();
+    return *m_MIMETypeRegistryThreadGlobalData;
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/ThreadGlobalData.h (253473 => 253474)


--- trunk/Source/WebCore/platform/ThreadGlobalData.h	2019-12-13 16:19:08 UTC (rev 253473)
+++ trunk/Source/WebCore/platform/ThreadGlobalData.h	2019-12-13 16:22:44 UTC (rev 253474)
@@ -43,6 +43,7 @@
 struct CachedResourceRequestInitiators;
 struct EventNames;
 struct ICUConverterWrapper;
+struct MIMETypeRegistryThreadGlobalData;
 
 #if USE(WEB_THREAD)
 class ThreadGlobalData : public ThreadSafeRefCounted<ThreadGlobalData> {
@@ -73,6 +74,8 @@
     bool isInRemoveAllEventListeners() const { return m_isInRemoveAllEventListeners; }
     void setIsInRemoveAllEventListeners(bool value) { m_isInRemoveAllEventListeners = value; }
 
+    const MIMETypeRegistryThreadGlobalData& mimeTypeRegistryThreadGlobalData();
+
 private:
     std::unique_ptr<CachedResourceRequestInitiators> m_cachedResourceRequestInitiators;
     std::unique_ptr<EventNames> m_eventNames;
@@ -87,6 +90,7 @@
     bool m_isInRemoveAllEventListeners { false };
 
     std::unique_ptr<ICUConverterWrapper> m_cachedConverterICU;
+    std::unique_ptr<MIMETypeRegistryThreadGlobalData> m_MIMETypeRegistryThreadGlobalData;
 
     WEBCORE_EXPORT friend ThreadGlobalData& threadGlobalData();
 };

Modified: trunk/Source/WebCore/workers/WorkerGlobalScope.h (253473 => 253474)


--- trunk/Source/WebCore/workers/WorkerGlobalScope.h	2019-12-13 16:19:08 UTC (rev 253473)
+++ trunk/Source/WebCore/workers/WorkerGlobalScope.h	2019-12-13 16:22:44 UTC (rev 253474)
@@ -122,6 +122,8 @@
 
     void addConsoleMessage(std::unique_ptr<Inspector::ConsoleMessage>&&) final;
 
+    SecurityOrigin& topOrigin() const final { return m_topOrigin.get(); }
+
     Crypto& crypto();
     Performance& performance() const;
 
@@ -168,7 +170,6 @@
 
     bool shouldBypassMainWorldContentSecurityPolicy() const final { return m_shouldBypassMainWorldContentSecurityPolicy; }
     bool isJSExecutionForbidden() const final;
-    SecurityOrigin& topOrigin() const final { return m_topOrigin.get(); }
 
 #if ENABLE(WEB_CRYPTO)
     bool wrapCryptoKey(const Vector<uint8_t>& key, Vector<uint8_t>& wrappedKey) final;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to