Bug 1500780 - CreateImageBitmap should handle OOM as InvalidState error, r=aosmond
authorAndrea Marchesini <amarchesini@mozilla.com>
Tue, 23 Oct 2018 23:35:43 +0200
changeset 490921 b273730d6149f687c46ed375ccc47674a3ef5afd
parent 490920 083f0be93a9f9da00b886cba36ca1e48fc168f5b
child 490922 dcaf26b9678bf7183892c56fe3dfcb52f7c393d9
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersaosmond
bugs1500780
milestone65.0a1
Bug 1500780 - CreateImageBitmap should handle OOM as InvalidState error, r=aosmond
dom/canvas/ImageBitmap.cpp
testing/web-platform/meta/2dcontext/imagebitmap/createImageBitmap-invalid-args.html.ini
testing/web-platform/tests/2dcontext/imagebitmap/createImageBitmap-invalid-args.html
--- a/dom/canvas/ImageBitmap.cpp
+++ b/dom/canvas/ImageBitmap.cpp
@@ -991,25 +991,25 @@ ImageBitmap::CreateInternal(nsIGlobalObj
     cropRect.MoveTo(0, 0);
     needToReportMemoryAllocation = true;
   }
   else {
     croppedSurface = surface;
   }
 
   if (NS_WARN_IF(!croppedSurface)) {
-    aRv.Throw(NS_ERROR_NOT_AVAILABLE);
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return nullptr;
   }
 
   // Create an Image from the SourceSurface.
   RefPtr<layers::Image> data = CreateImageFromSurface(croppedSurface);
 
   if (NS_WARN_IF(!data)) {
-    aRv.Throw(NS_ERROR_NOT_AVAILABLE);
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return nullptr;
   }
 
   RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
 
   if (needToReportMemoryAllocation) {
     ret->mAllocatedImageData = true;
   }
@@ -1066,17 +1066,17 @@ ImageBitmap::CreateInternal(nsIGlobalObj
                                                        FORMAT,
                                                        imageSize,
                                                        aCropRect,
                                                        getter_AddRefs(data));
     task->Dispatch(Canceling, aRv);
   }
 
   if (NS_WARN_IF(!data)) {
-    aRv.Throw(NS_ERROR_NOT_AVAILABLE);
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return nullptr;
   }
 
   // Create an ImageBimtap.
   RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, alphaType);
 
   ret->mAllocatedImageData = true;
 
@@ -2260,17 +2260,18 @@ CreateImageBitmapFromBlob::OnImageReady(
   MOZ_ASSERT(aImgContainer);
 
   // Get the surface out.
   uint32_t frameFlags = imgIContainer::FLAG_SYNC_DECODE | imgIContainer::FLAG_WANT_DATA_SURFACE;
   uint32_t whichFrame = imgIContainer::FRAME_FIRST;
   RefPtr<SourceSurface> surface = aImgContainer->GetFrame(whichFrame, frameFlags);
 
   if (NS_WARN_IF(!surface)) {
-    DecodeAndCropBlobCompletedMainThread(nullptr, NS_ERROR_FAILURE);
+    DecodeAndCropBlobCompletedMainThread(nullptr,
+                                         NS_ERROR_DOM_INVALID_STATE_ERR);
     return NS_OK;
   }
 
   // Store the sourceSize value for the DecodeAndCropBlobCompletedMainThread call.
   mSourceSize = surface->GetSize();
 
   // Crop the source surface if needed.
   RefPtr<SourceSurface> croppedSurface = surface;
@@ -2289,25 +2290,27 @@ CreateImageBitmapFromBlob::OnImageReady(
     //       decode the blob off the main thread. Re-check if we should do
     //       cropping at this moment again there.
     RefPtr<DataSourceSurface> dataSurface = surface->GetDataSurface();
     croppedSurface = CropAndCopyDataSourceSurface(dataSurface, mCropRect.ref());
     mCropRect->MoveTo(0, 0);
   }
 
   if (NS_WARN_IF(!croppedSurface)) {
-    DecodeAndCropBlobCompletedMainThread(nullptr, NS_ERROR_FAILURE);
+    DecodeAndCropBlobCompletedMainThread(nullptr,
+                                         NS_ERROR_DOM_INVALID_STATE_ERR);
     return NS_OK;
   }
 
   // Create an Image from the source surface.
   RefPtr<layers::Image> image = CreateImageFromSurface(croppedSurface);
 
   if (NS_WARN_IF(!image)) {
-    DecodeAndCropBlobCompletedMainThread(nullptr, NS_ERROR_FAILURE);
+    DecodeAndCropBlobCompletedMainThread(nullptr,
+                                         NS_ERROR_DOM_INVALID_STATE_ERR);
     return NS_OK;
   }
 
   DecodeAndCropBlobCompletedMainThread(image, NS_OK);
   return NS_OK;
 }
 
 void
--- a/testing/web-platform/meta/2dcontext/imagebitmap/createImageBitmap-invalid-args.html.ini
+++ b/testing/web-platform/meta/2dcontext/imagebitmap/createImageBitmap-invalid-args.html.ini
@@ -1,67 +1,43 @@
 [createImageBitmap-invalid-args.html]
-  [createImageBitmap with an HTMLCanvasElement source and oversized (unallocatable) crop region]
-    expected: FAIL
-
-  [createImageBitmap with an HTMLVideoElement source and oversized (unallocatable) crop region]
-    expected: FAIL
-
   [createImageBitmap with an OffscreenCanvas source and sw set to 0]
     expected: FAIL
 
   [createImageBitmap with an OffscreenCanvas source and sh set to 0]
     expected: FAIL
 
   [createImageBitmap with an OffscreenCanvas source and oversized (unallocatable) crop region]
     expected: FAIL
 
-  [createImageBitmap with an ImageData source and oversized (unallocatable) crop region]
-    expected: FAIL
-
-  [createImageBitmap with an ImageBitmap source and oversized (unallocatable) crop region]
-    expected: FAIL
-
   [createImageBitmap with an invalid OffscreenCanvas source.]
     expected: FAIL
 
   [createImageBitmap with a broken image source.]
     expected: FAIL
 
   [createImageBitmap with an available but undecodable image source.]
     expected: FAIL
 
   [createImageBitmap with a closed ImageBitmap.]
     expected: FAIL
 
-  [createImageBitmap with a bitmap HTMLImageElement source and oversized (unallocatable) crop region]
-    expected: FAIL
-
   [createImageBitmap with a bitmap SVGImageElement source and sw set to 0]
     expected: FAIL
 
   [createImageBitmap with a bitmap SVGImageElement source and sh set to 0]
     expected: FAIL
 
-  [createImageBitmap with a bitmap SVGImageElement source and oversized (unallocatable) crop region]
-    expected: FAIL
-
   [createImageBitmap with a vector SVGImageElement source and sw set to 0]
     expected: FAIL
 
   [createImageBitmap with a vector SVGImageElement source and sh set to 0]
     expected: FAIL
 
-  [createImageBitmap with a vector SVGImageElement source and oversized (unallocatable) crop region]
-    expected: FAIL
-
   [createImageBitmap with CanvasRenderingContext2D image source.]
     expected: FAIL
 
   [createImageBitmap with Uint8Array image source.]
     expected: FAIL
 
   [createImageBitmap with ArrayBuffer image source.]
     expected: FAIL
 
-  [createImageBitmap with an HTMLVideoElement from a data URL source and oversized (unallocatable) crop region]
-    expected: FAIL
-
--- a/testing/web-platform/tests/2dcontext/imagebitmap/createImageBitmap-invalid-args.html
+++ b/testing/web-platform/tests/2dcontext/imagebitmap/createImageBitmap-invalid-args.html
@@ -60,27 +60,33 @@ testCases = [
     description: 'createImageBitmap with <sourceType> source and sh set to 0',
     promiseTestFunction:
       (source, t) => {
         return promise_rejects(t, new RangeError(),
             createImageBitmap(source, 0, 0, 10, 0));
       }
   },
   {
-    // This case is not explicitly documented in the specification for
-    // createImageBitmap, but it is expected that internal failures cause
-    // InvalidStateError.
-    //
-    // Note: https://bugs.chromium.org/p/chromium/issues/detail?id=799025
     description: 'createImageBitmap with <sourceType> source and oversized ' +
         '(unallocatable) crop region',
     promiseTestFunction:
       (source, t) => {
-        return promise_rejects(t, new DOMException('', 'InvalidStateError'),
-            createImageBitmap(source, 0, 0, 100000000, 100000000));
+        return createImageBitmap(source, 0, 0, 100000000, 100000000)
+          .then(i => {
+            assert_equals(i.width, 100000000);
+            assert_equals(i.height, 100000000);
+          })
+          .catch(e => {
+            // This case is not explicitly documented in the specification for
+            // createImageBitmap, but it is expected that internal failures
+            // cause InvalidStateError.
+            //
+            // Note: https://bugs.chromium.org/p/chromium/issues/detail?id=799025
+            assert_throws(e, function() { throw e }, new DOMException('', 'InvalidStateError'));
+          });
       }
   },
 ];
 
 // Generate the test matrix for each sourceType + testCase combo.
 imageSourceTypes.forEach(imageSourceType => {
   testCases.forEach(testCase => {
     let description = testCase.description.replace('<sourceType>',