b=385584, crash with toDataURL on large canvas, r=stuart
authorvladimir@pobox.com
Mon, 25 Jun 2007 09:24:19 -0700
changeset 2756 41198ea72101a10385136df817f6fc2438f80910
parent 2755 c047ab08dda975a71875cc9fdb2da83180c81461
child 2757 f2ecfaf342fecfafb78b0cacdeb512003d5ac6dd
push idunknown
push userunknown
push dateunknown
reviewersstuart
bugs385584
milestone1.9a6pre
b=385584, crash with toDataURL on large canvas, r=stuart
content/canvas/src/nsCanvasRenderingContext2D.cpp
content/html/content/src/nsHTMLCanvasElement.cpp
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -715,16 +715,24 @@ nsCanvasRenderingContext2D::SetDimension
     return NS_OK;
 }
  
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::Render(nsIRenderingContext *rc)
 {
     nsresult rv = NS_OK;
 
+    if (!mSurface || !mCairo ||
+        cairo_surface_status(mSurface) != CAIRO_STATUS_SUCCESS ||
+        cairo_status(mCairo) != CAIRO_STATUS_SUCCESS)
+        return NS_ERROR_FAILURE;
+
+    if (!mThebesSurface)
+        return NS_ERROR_FAILURE;
+
     gfxContext* ctx = (gfxContext*) rc->GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT);
     nsRefPtr<gfxPattern> pat = new gfxPattern(mThebesSurface);
 
     // XXX I don't want to use PixelSnapped here, but layout doesn't guarantee
     // pixel alignment for this stuff!
     ctx->NewPath();
     ctx->PixelSnappedRectangleAndSetPattern(gfxRect(0, 0, mWidth, mHeight), pat);
     ctx->Fill();
@@ -743,24 +751,22 @@ nsCanvasRenderingContext2D::RenderToSurf
     return NS_OK;
 }
  
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::GetInputStream(const nsACString& aMimeType,
                                            const nsAString& aEncoderOptions,
                                            nsIInputStream **aStream)
 {
+    if (!mSurface || cairo_surface_status(mSurface) != CAIRO_STATUS_SUCCESS)
+        return NS_ERROR_FAILURE;
+
     nsCString conid(NS_LITERAL_CSTRING("@mozilla.org/image/encoder;2?type="));
     conid += aMimeType;
 
-    if (cairo_status(mCairo)) {
-        fprintf (stderr, "Cairo error! %d %s\n", cairo_status(mCairo), cairo_status_to_string(cairo_status(mCairo)));
-        fflush (stderr);
-    }
-
     nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(conid.get());
     if (!encoder)
         return NS_ERROR_FAILURE;
 
     if (mImageSurfaceData) {
         encoder->InitFromData(mImageSurfaceData,
                               mWidth * mHeight * 4, mWidth, mHeight, mWidth * 4,
                               imgIEncoder::INPUT_FORMAT_HOSTARGB,
--- a/content/html/content/src/nsHTMLCanvasElement.cpp
+++ b/content/html/content/src/nsHTMLCanvasElement.cpp
@@ -450,20 +450,26 @@ nsHTMLCanvasElement::GetContext(const ns
     mCurrentContext = do_CreateInstance(nsPromiseFlatCString(ctxString).get(), &rv);
     if (rv == NS_ERROR_OUT_OF_MEMORY)
       return NS_ERROR_OUT_OF_MEMORY;
     if (NS_FAILED(rv))
       // XXX ERRMSG we need to report an error to developers here! (bug 329026)
       return NS_ERROR_INVALID_ARG;
 
     rv = mCurrentContext->SetCanvasElement(this);
-    NS_ENSURE_SUCCESS(rv, rv);
+    if (NS_FAILED(rv)) {
+      mCurrentContext = nsnull;
+      return rv;
+    }
 
     rv = UpdateContext();
-    NS_ENSURE_SUCCESS(rv, rv);
+    if (NS_FAILED(rv)) {
+      mCurrentContext = nsnull;
+      return rv;
+    }
 
     mCurrentContextId.Assign(aContextId);
   } else if (!mCurrentContextId.Equals(aContextId)) {
     //XXX eventually allow for more than one active context on a given canvas
     return NS_ERROR_INVALID_ARG;
   }
 
   NS_ADDREF (*aContext = mCurrentContext);