Index: third_party/WebKit/Source/core/frame/ImageBitmap.cpp |
diff --git a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp |
index 990fd97df9293e470145e6e37e5d0c9368ae8726..8c8c20f9b8007c2d4e591f4f3b2f2c427af4b0b9 100644 |
--- a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp |
+++ b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp |
@@ -12,6 +12,7 @@ |
#include "platform/image-decoders/ImageDecoder.h" |
#include "third_party/skia/include/core/SkCanvas.h" |
#include "third_party/skia/include/core/SkSurface.h" |
+#include "wtf/CheckedNumeric.h" |
#include "wtf/PtrUtil.h" |
#include "wtf/RefPtr.h" |
#include <memory> |
@@ -101,6 +102,18 @@ ParsedOptions parseOptions(const ImageBitmapOptions& options, Optional<IntRect> |
return parsedOptions; |
} |
+bool couldDstSizeOverflow(int width, int height) |
Justin Novosad
2016/08/18 16:42:14
DstBufferSizeHasOverflow
xidachen
2016/08/22 12:02:28
Done.
|
+{ |
+ CheckedNumeric<int> totalBytes = width; |
Justin Novosad
2016/08/18 16:42:14
Why int and not size_t? If there is code somewhere
xidachen
2016/08/22 12:02:28
Done.
|
+ totalBytes *= height; |
+ if (!totalBytes.IsValid()) |
Justin Novosad
2016/08/18 16:42:14
This one is not necessary. Just check is Valid at
xidachen
2016/08/22 12:02:28
Done.
|
+ return true; |
+ totalBytes *= 4; |
Justin Novosad
2016/08/18 16:42:14
This hardcoded 4 is dangerous. We will soon suppor
xidachen
2016/08/22 12:02:28
Done.
|
+ if (!totalBytes.IsValid()) |
+ return true; |
+ return false; |
+} |
+ |
} // namespace |
static std::unique_ptr<uint8_t[]> copySkImageData(SkImage* input, const SkImageInfo& info) |
@@ -289,6 +302,10 @@ ImageBitmap::ImageBitmap(HTMLImageElement* image, Optional<IntRect> cropRect, Do |
{ |
RefPtr<Image> input = image->cachedImage()->getImage(); |
ParsedOptions parsedOptions = parseOptions(options, cropRect, image->bitmapSourceSize()); |
+ if (couldDstSizeOverflow(parsedOptions.cropRect.width(), parsedOptions.cropRect.height())) |
Justin Novosad
2016/08/18 16:42:14
This repeated bit of code could be made simpler if
xidachen
2016/08/22 12:02:28
Moving the check to the place where overflow occur
|
+ return; |
+ if (parsedOptions.shouldScaleInput && couldDstSizeOverflow(parsedOptions.resizeWidth, parsedOptions.resizeHeight)) |
+ return; |
if (options.colorSpaceConversion() == "none") |
m_image = cropImage(input.get(), parsedOptions, PremultiplyAlpha, ImageDecoder::GammaAndColorProfileIgnored); |
@@ -315,6 +332,10 @@ ImageBitmap::ImageBitmap(HTMLVideoElement* video, Optional<IntRect> cropRect, Do |
if (video->webMediaPlayer()) |
playerSize = video->webMediaPlayer()->naturalSize(); |
ParsedOptions parsedOptions = parseOptions(options, cropRect, video->bitmapSourceSize()); |
+ if (couldDstSizeOverflow(parsedOptions.cropRect.width(), parsedOptions.cropRect.height())) |
+ return; |
+ if (parsedOptions.shouldScaleInput && couldDstSizeOverflow(parsedOptions.resizeWidth, parsedOptions.resizeHeight)) |
+ return; |
IntRect videoRect = IntRect(IntPoint(), playerSize); |
IntRect srcRect = intersection(parsedOptions.cropRect, videoRect); |
@@ -351,6 +372,10 @@ ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, Optional<IntRect> cropRect, |
ASSERT(canvas->isPaintable()); |
RefPtr<Image> input = canvas->copiedImage(BackBuffer, PreferAcceleration); |
ParsedOptions parsedOptions = parseOptions(options, cropRect, canvas->bitmapSourceSize()); |
+ if (couldDstSizeOverflow(parsedOptions.cropRect.width(), parsedOptions.cropRect.height())) |
+ return; |
+ if (parsedOptions.shouldScaleInput && couldDstSizeOverflow(parsedOptions.resizeWidth, parsedOptions.resizeHeight)) |
+ return; |
bool isPremultiplyAlphaReverted = false; |
if (!parsedOptions.premultiplyAlpha) { |
@@ -393,6 +418,10 @@ ImageBitmap::ImageBitmap(ImageData* data, Optional<IntRect> cropRect, const Imag |
// TODO(xidachen): implement the resize option |
IntRect dataSrcRect = IntRect(IntPoint(), data->size()); |
ParsedOptions parsedOptions = parseOptions(options, cropRect, data->bitmapSourceSize()); |
+ if (couldDstSizeOverflow(parsedOptions.cropRect.width(), parsedOptions.cropRect.height())) |
+ return; |
+ if (parsedOptions.shouldScaleInput && couldDstSizeOverflow(parsedOptions.resizeWidth, parsedOptions.resizeHeight)) |
+ return; |
IntRect srcRect = cropRect ? intersection(parsedOptions.cropRect, dataSrcRect) : dataSrcRect; |
// treat non-premultiplyAlpha as a special case |
@@ -492,6 +521,10 @@ ImageBitmap::ImageBitmap(ImageBitmap* bitmap, Optional<IntRect> cropRect, const |
if (!input) |
return; |
ParsedOptions parsedOptions = parseOptions(options, cropRect, input->size()); |
+ if (couldDstSizeOverflow(parsedOptions.cropRect.width(), parsedOptions.cropRect.height())) |
+ return; |
+ if (parsedOptions.shouldScaleInput && couldDstSizeOverflow(parsedOptions.resizeWidth, parsedOptions.resizeHeight)) |
+ return; |
m_image = cropImage(input.get(), parsedOptions, bitmap->isPremultiplied() ? PremultiplyAlpha : DontPremultiplyAlpha); |
if (!m_image) |
@@ -505,6 +538,10 @@ ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image, Optional<IntRect> |
bool originClean = image->originClean(); |
RefPtr<Image> input = image; |
ParsedOptions parsedOptions = parseOptions(options, cropRect, input->size()); |
+ if (couldDstSizeOverflow(parsedOptions.cropRect.width(), parsedOptions.cropRect.height())) |
+ return; |
+ if (parsedOptions.shouldScaleInput && couldDstSizeOverflow(parsedOptions.resizeWidth, parsedOptions.resizeHeight)) |
+ return; |
m_image = cropImage(input.get(), parsedOptions, DontPremultiplyAlpha); |
if (!m_image) |