Bug 1257717 - throw InvalidStateError when CreatePattern fails to snapshot source. r=jrmuizel
authorLee Salzman <lsalzman@mozilla.com>
Thu, 14 Apr 2016 16:20:12 -0400
changeset 351795 9a7955d81761e0c6e847099360cbafff295c057c
parent 351794 bd74613c5184aeebba2f24dfab46af044e4e4a9a
child 351796 1411186a9603c9b897f7942c8a2781a81766082d
push id15527
push userbmo:rail@mozilla.com
push dateFri, 15 Apr 2016 01:44:41 +0000
reviewersjrmuizel
bugs1257717
milestone48.0a1
Bug 1257717 - throw InvalidStateError when CreatePattern fails to snapshot source. r=jrmuizel
dom/canvas/CanvasRenderingContext2D.cpp
gfx/2d/DrawTargetSkia.cpp
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -2116,16 +2116,24 @@ CanvasRenderingContext2D::CreatePattern(
       return nullptr;
     }
 
     // Special case for Canvas, which could be an Azure canvas!
     nsICanvasRenderingContextInternal *srcCanvas = canvas->GetContextAtIndex(0);
     if (srcCanvas) {
       // This might not be an Azure canvas!
       RefPtr<SourceSurface> srcSurf = srcCanvas->GetSurfaceSnapshot();
+      if (!srcSurf) {
+        JSContext* context = nsContentUtils::GetCurrentJSContext();
+        if (context) {
+          JS_ReportWarning(context, "CanvasRenderingContext2D.createPattern() failed to snapshot source canvas.");
+        }
+        aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+        return nullptr;
+      }
 
       RefPtr<CanvasPattern> pat =
         new CanvasPattern(this, srcSurf, repeatMode, htmlElement->NodePrincipal(), canvas->IsWriteOnly(), false);
 
       return pat.forget();
     }
   } else if (aSource.IsHTMLImageElement()) {
     HTMLImageElement* img = &aSource.GetAsHTMLImageElement();
@@ -2137,16 +2145,24 @@ CanvasRenderingContext2D::CreatePattern(
     htmlElement = img;
   } else if (aSource.IsHTMLVideoElement()) {
     htmlElement = &aSource.GetAsHTMLVideoElement();
   } else {
     // Special case for ImageBitmap
     ImageBitmap& imgBitmap = aSource.GetAsImageBitmap();
     EnsureTarget();
     RefPtr<SourceSurface> srcSurf = imgBitmap.PrepareForDrawTarget(mTarget);
+    if (!srcSurf) {
+      JSContext* context = nsContentUtils::GetCurrentJSContext();
+      if (context) {
+        JS_ReportWarning(context, "CanvasRenderingContext2D.createPattern() failed to prepare source ImageBitmap.");
+      }
+      aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+      return nullptr;
+    }
 
     // An ImageBitmap never taints others so we set principalForSecurityCheck to
     // nullptr and set CORSUsed to true for passing the security check in
     // CanvasUtils::DoDrawImageSecurityCheck().
     RefPtr<CanvasPattern> pat =
       new CanvasPattern(this, srcSurf, repeatMode, nullptr, false, true);
 
     return pat.forget();
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -94,16 +94,21 @@ ReleaseTemporarySurface(void* aPixels, v
   }
 }
 
 static SkBitmap
 GetBitmapForSurface(SourceSurface* aSurface)
 {
   SkBitmap bitmap;
 
+  if (!aSurface) {
+    gfxDebug() << "Creating empty Skia bitmap from null SourceSurface";
+    return bitmap;
+  }
+
   if (aSurface->GetType() == SurfaceType::SKIA) {
     bitmap = static_cast<SourceSurfaceSkia*>(aSurface)->GetBitmap();
     return bitmap;
   }
 
   DataSourceSurface* surf = aSurface->GetDataSurface().take();
   if (!surf) {
     gfxDevCrash(LogReason::SourceSurfaceIncompatible) << "Non-Skia SourceSurfaces need to be DataSourceSurfaces";