Chromium Code Reviews| 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) |