Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(400)

Unified Diff: third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp

Issue 1414553002: Fix out-of-memory crashes related to ArrayBuffer allocation Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase+more tweaks Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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());
« no previous file with comments | « third_party/WebKit/Source/core/html/HTMLCanvasElement.h ('k') | third_party/WebKit/Source/core/html/ImageData.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698