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

Side by Side Diff: third_party/WebKit/Source/core/frame/ImageBitmap.cpp

Issue 2500493002: Prevent bad casting in ImageBitmap when calling ArrayBuffer::createOrNull (Closed)
Patch Set: Created 4 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/frame/ImageBitmap.h" 5 #include "core/frame/ImageBitmap.h"
6 6
7 #include "core/html/HTMLCanvasElement.h" 7 #include "core/html/HTMLCanvasElement.h"
8 #include "core/html/HTMLVideoElement.h" 8 #include "core/html/HTMLVideoElement.h"
9 #include "core/html/ImageData.h" 9 #include "core/html/ImageData.h"
10 #include "platform/graphics/skia/SkiaUtils.h" 10 #include "platform/graphics/skia/SkiaUtils.h"
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 return false; 118 return false;
119 totalBytes = options.resizeWidth; 119 totalBytes = options.resizeWidth;
120 totalBytes *= options.resizeHeight; 120 totalBytes *= options.resizeHeight;
121 totalBytes *= options.bytesPerPixel; 121 totalBytes *= options.bytesPerPixel;
122 if (!totalBytes.IsValid()) 122 if (!totalBytes.IsValid())
123 return true; 123 return true;
124 124
125 return false; 125 return false;
126 } 126 }
127 127
128 bool arrayBufferCreationHasOverflow(unsigned width, unsigned height) {
129 CheckedNumeric<unsigned> numElement = width;
130 numElement *= height;
Justin Novosad 2016/11/11 14:40:29 It'a a bit wasteful that this product is always re
131 if (!numElement.IsValid())
132 return true;
133 return false;
134 }
135
128 } // namespace 136 } // namespace
129 137
130 static PassRefPtr<Uint8Array> copySkImageData(SkImage* input, 138 static PassRefPtr<Uint8Array> copySkImageData(SkImage* input,
131 const SkImageInfo& info) { 139 const SkImageInfo& info) {
140 if (arrayBufferCreationHasOverflow(static_cast<unsigned>(input->width()),
141 static_cast<unsigned>(input->height())))
142 return nullptr;
132 // The function dstBufferSizeHasOverflow() is being called at the beginning of 143 // The function dstBufferSizeHasOverflow() is being called at the beginning of
133 // each ImageBitmap() constructor, which makes sure that doing 144 // each ImageBitmap() constructor, which makes sure that doing
134 // width * height * bytesPerPixel will never overflow size_t. 145 // width * height * bytesPerPixel will never overflow size_t.
135 size_t width = static_cast<size_t>(input->width()); 146 size_t width = static_cast<size_t>(input->width());
Justin Novosad 2016/11/11 14:40:29 Here width is size_t, but the check was done using
136 RefPtr<ArrayBuffer> dstBuffer = 147 RefPtr<ArrayBuffer> dstBuffer =
137 ArrayBuffer::createOrNull(width * input->height(), info.bytesPerPixel()); 148 ArrayBuffer::createOrNull(width * input->height(), info.bytesPerPixel());
138 if (!dstBuffer) 149 if (!dstBuffer)
139 return nullptr; 150 return nullptr;
140 RefPtr<Uint8Array> dstPixels = 151 RefPtr<Uint8Array> dstPixels =
141 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength()); 152 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength());
142 input->readPixels(info, dstPixels->data(), width * info.bytesPerPixel(), 0, 153 input->readPixels(info, dstPixels->data(), width * info.bytesPerPixel(), 0,
143 0); 154 0);
144 return dstPixels; 155 return dstPixels;
145 } 156 }
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 ImageDecoder::ColorSpaceOption colorSpaceOp = 290 ImageDecoder::ColorSpaceOption colorSpaceOp =
280 ImageDecoder::ColorSpaceApplied) { 291 ImageDecoder::ColorSpaceApplied) {
281 ASSERT(image); 292 ASSERT(image);
282 IntRect imgRect(IntPoint(), IntSize(image->width(), image->height())); 293 IntRect imgRect(IntPoint(), IntSize(image->width(), image->height()));
283 const IntRect srcRect = intersection(imgRect, parsedOptions.cropRect); 294 const IntRect srcRect = intersection(imgRect, parsedOptions.cropRect);
284 295
285 // In the case when cropRect doesn't intersect the source image and it 296 // In the case when cropRect doesn't intersect the source image and it
286 // requires a umpremul image We immediately return a transparent black image 297 // requires a umpremul image We immediately return a transparent black image
287 // with cropRect.size() 298 // with cropRect.size()
288 if (srcRect.isEmpty() && !parsedOptions.premultiplyAlpha) { 299 if (srcRect.isEmpty() && !parsedOptions.premultiplyAlpha) {
300 if (arrayBufferCreationHasOverflow(parsedOptions.resizeWidth,
301 parsedOptions.resizeHeight))
302 return nullptr;
289 SkImageInfo info = 303 SkImageInfo info =
290 SkImageInfo::Make(parsedOptions.resizeWidth, parsedOptions.resizeHeight, 304 SkImageInfo::Make(parsedOptions.resizeWidth, parsedOptions.resizeHeight,
291 kN32_SkColorType, kUnpremul_SkAlphaType); 305 kN32_SkColorType, kUnpremul_SkAlphaType);
292 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull( 306 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull(
293 static_cast<size_t>(info.width()) * info.height(), 307 static_cast<size_t>(info.width()) * info.height(),
294 info.bytesPerPixel()); 308 info.bytesPerPixel());
295 if (!dstBuffer) 309 if (!dstBuffer)
296 return nullptr; 310 return nullptr;
297 RefPtr<Uint8Array> dstPixels = 311 RefPtr<Uint8Array> dstPixels =
298 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength()); 312 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength());
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 if (!m_image) 521 if (!m_image)
508 return; 522 return;
509 m_image->setPremultiplied(isImageBitmapPremultiplied); 523 m_image->setPremultiplied(isImageBitmapPremultiplied);
510 m_image->setOriginClean(isImageBitmapOriginClean); 524 m_image->setOriginClean(isImageBitmapOriginClean);
511 } 525 }
512 526
513 static sk_sp<SkImage> scaleSkImage(sk_sp<SkImage> skImage, 527 static sk_sp<SkImage> scaleSkImage(sk_sp<SkImage> skImage,
514 unsigned resizeWidth, 528 unsigned resizeWidth,
515 unsigned resizeHeight, 529 unsigned resizeHeight,
516 SkFilterQuality resizeQuality) { 530 SkFilterQuality resizeQuality) {
531 if (arrayBufferCreationHasOverflow(resizeWidth, resizeHeight))
532 return nullptr;
517 SkImageInfo resizedInfo = SkImageInfo::Make( 533 SkImageInfo resizedInfo = SkImageInfo::Make(
518 resizeWidth, resizeHeight, kN32_SkColorType, kUnpremul_SkAlphaType); 534 resizeWidth, resizeHeight, kN32_SkColorType, kUnpremul_SkAlphaType);
519 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull( 535 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull(
520 resizeWidth * resizeHeight, resizedInfo.bytesPerPixel()); 536 resizeWidth * resizeHeight, resizedInfo.bytesPerPixel());
521 if (!dstBuffer) 537 if (!dstBuffer)
522 return nullptr; 538 return nullptr;
523 RefPtr<Uint8Array> resizedPixels = 539 RefPtr<Uint8Array> resizedPixels =
524 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength()); 540 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength());
525 SkPixmap pixmap( 541 SkPixmap pixmap(
526 resizedInfo, resizedPixels->data(), 542 resizedInfo, resizedPixels->data(),
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 sk_sp<SkImage> skImage; 575 sk_sp<SkImage> skImage;
560 if (parsedOptions.cropRect == IntRect(IntPoint(), data->size())) { 576 if (parsedOptions.cropRect == IntRect(IntPoint(), data->size())) {
561 swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow, 577 swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow,
562 parsedOptions.flipY); 578 parsedOptions.flipY);
563 skImage = 579 skImage =
564 SkImage::MakeRasterCopy(SkPixmap(info, srcAddr, dstPixelBytesPerRow)); 580 SkImage::MakeRasterCopy(SkPixmap(info, srcAddr, dstPixelBytesPerRow));
565 // restore the original ImageData 581 // restore the original ImageData
566 swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow, 582 swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow,
567 parsedOptions.flipY); 583 parsedOptions.flipY);
568 } else { 584 } else {
585 if (arrayBufferCreationHasOverflow(
586 static_cast<unsigned>(parsedOptions.cropRect.width()),
587 static_cast<unsigned>(parsedOptions.cropRect.height())))
588 return;
569 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull( 589 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull(
570 static_cast<size_t>(parsedOptions.cropRect.height()) * 590 static_cast<size_t>(parsedOptions.cropRect.height()) *
571 parsedOptions.cropRect.width(), 591 parsedOptions.cropRect.width(),
572 bytesPerPixel); 592 bytesPerPixel);
573 if (!dstBuffer) 593 if (!dstBuffer)
574 return; 594 return;
575 RefPtr<Uint8Array> copiedDataBuffer = 595 RefPtr<Uint8Array> copiedDataBuffer =
576 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength()); 596 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength());
577 if (!srcRect.isEmpty()) { 597 if (!srcRect.isEmpty()) {
578 IntPoint srcPoint = IntPoint( 598 IntPoint srcPoint = IntPoint(
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
857 void ImageBitmap::adjustDrawRects(FloatRect* srcRect, 877 void ImageBitmap::adjustDrawRects(FloatRect* srcRect,
858 FloatRect* dstRect) const {} 878 FloatRect* dstRect) const {}
859 879
860 FloatSize ImageBitmap::elementSize(const FloatSize&) const { 880 FloatSize ImageBitmap::elementSize(const FloatSize&) const {
861 return FloatSize(width(), height()); 881 return FloatSize(width(), height());
862 } 882 }
863 883
864 DEFINE_TRACE(ImageBitmap) {} 884 DEFINE_TRACE(ImageBitmap) {}
865 885
866 } // namespace blink 886 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698