Index: third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp |
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp |
index bf12c2feaf31ba82571f7577f0a1568762032aff..a2d37a767d577fb92c8a5af3792d06b8ac9e361f 100644 |
--- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp |
+++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp |
@@ -455,7 +455,11 @@ String HTMLCanvasElement::toEncodingMimeType(const String& mimeType) |
const AtomicString HTMLCanvasElement::imageSourceURL() const |
{ |
- return AtomicString(toDataURLInternal(DefaultMimeType, 0, FrontBuffer)); |
+ NonThrowableExceptionState exceptionState; |
+ AtomicString dataURL(toDataURLInternal(DefaultMimeType, 0, FrontBuffer, exceptionState)); |
+ if (exceptionState.hadException()) |
+ return AtomicString("data:,"); |
+ return dataURL; |
} |
void HTMLCanvasElement::prepareSurfaceForPaintingIfNeeded() const |
@@ -465,7 +469,7 @@ void HTMLCanvasElement::prepareSurfaceForPaintingIfNeeded() const |
m_imageBuffer->prepareSurfaceForPaintingIfNeeded(); |
} |
-ImageData* HTMLCanvasElement::toImageData(SourceDrawingBuffer sourceBuffer) const |
+ImageData* HTMLCanvasElement::toImageData(SourceDrawingBuffer sourceBuffer, ExceptionState& exceptionState) const |
{ |
ImageData* imageData; |
if (is3D()) { |
@@ -475,7 +479,16 @@ ImageData* HTMLCanvasElement::toImageData(SourceDrawingBuffer sourceBuffer) cons |
return imageData; |
m_context->paintRenderingResultsToCanvas(sourceBuffer); |
- imageData = ImageData::create(m_size); |
+ imageData = ImageData::create(m_size, exceptionState); |
+ // Note: we rethrow exceptions from ImageData creation, which is not |
+ // mandated by the specification because using an ImageData intermediate |
+ // for toBlob and toDataURL is an implementation choice. As a result of |
+ // this rethrow, a RangeError exception may be thrown when there is |
+ // insufficient available memory. Even though the exception is unspec'ed, |
+ // it was ascertained that to throw from here will generally result in a |
+ // better outcome than to crash the process. |
+ if (exceptionState.hadException()) |
+ return nullptr; |
RefPtr<SkImage> snapshot = buffer()->newSkImageSnapshot(PreferNoAcceleration); |
if (snapshot) { |
SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRGBA_8888_SkColorType, kUnpremul_SkAlphaType); |
@@ -484,7 +497,9 @@ ImageData* HTMLCanvasElement::toImageData(SourceDrawingBuffer sourceBuffer) cons |
return imageData; |
} |
- imageData = ImageData::create(m_size); |
+ imageData = ImageData::create(m_size, exceptionState); |
+ if (exceptionState.hadException()) |
+ return nullptr; |
if (!m_context) |
return imageData; |
@@ -499,14 +514,17 @@ ImageData* HTMLCanvasElement::toImageData(SourceDrawingBuffer sourceBuffer) cons |
return imageData; |
} |
-String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double& quality, SourceDrawingBuffer sourceBuffer) const |
+String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double& quality, SourceDrawingBuffer sourceBuffer, ExceptionState& exceptionState) const |
{ |
if (!isPaintable()) |
return String("data:,"); |
String encodingMimeType = toEncodingMimeType(mimeType); |
- ImageData* imageData = toImageData(sourceBuffer); |
+ ImageData* imageData = toImageData(sourceBuffer, exceptionState); |
+ if (exceptionState.hadException()) |
+ return String(); |
+ |
ScopedDisposal<ImageData> disposer(imageData); |
return ImageDataBuffer(imageData->size(), imageData->data()->data()).toDataURL(encodingMimeType, quality); |
@@ -525,7 +543,7 @@ String HTMLCanvasElement::toDataURL(const String& mimeType, const ScriptValue& q |
quality = v8Value.As<v8::Number>()->Value(); |
} |
} |
- return toDataURLInternal(mimeType, quality, BackBuffer); |
+ return toDataURLInternal(mimeType, quality, BackBuffer, exceptionState); |
} |
void HTMLCanvasElement::toBlob(FileCallback* callback, const String& mimeType, const ScriptValue& qualityArgument, ExceptionState& exceptionState) |
@@ -551,8 +569,11 @@ void HTMLCanvasElement::toBlob(FileCallback* callback, const String& mimeType, c |
String encodingMimeType = toEncodingMimeType(mimeType); |
- ImageData* imageData = toImageData(BackBuffer); |
- // imageData unref its data, which we still keep alive for the async toBlob thread |
+ ImageData* imageData = toImageData(BackBuffer, exceptionState); |
+ if (exceptionState.hadException()) |
+ return; |
+ |
+ // ImageData unrefs its data, which we still keep alive for the async toBlob thread |
ScopedDisposal<ImageData> disposer(imageData); |
// Add a ref to keep image data alive until completion of encoding |
RefPtr<DOMUint8ClampedArray> imageDataRef(imageData->data()); |