Diff
Added: trunk/LayoutTests/fast/canvas/canvas-getImageData-large-crash-expected.txt (0 => 94457)
--- trunk/LayoutTests/fast/canvas/canvas-getImageData-large-crash-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/canvas/canvas-getImageData-large-crash-expected.txt 2011-09-02 22:32:44 UTC (rev 94457)
@@ -0,0 +1 @@
+PASSED (If this page did not crash.)
Added: trunk/LayoutTests/fast/canvas/canvas-getImageData-large-crash.html (0 => 94457)
--- trunk/LayoutTests/fast/canvas/canvas-getImageData-large-crash.html (rev 0)
+++ trunk/LayoutTests/fast/canvas/canvas-getImageData-large-crash.html 2011-09-02 22:32:44 UTC (rev 94457)
@@ -0,0 +1,14 @@
+<html>
+<head>
+<script>
+if (window.layoutTestController)
+ layoutTestController.dumpAsText(false);
+
+var canvas = document.createElement("canvas");
+canvas.getContext("2d").getImageData(10, 0xffffffff, 2147483647,10);
+</script>
+</head>
+<body>
+PASSED (If this page did not crash.)
+</body>
+</html>
Modified: trunk/Source/_javascript_Core/ChangeLog (94456 => 94457)
--- trunk/Source/_javascript_Core/ChangeLog 2011-09-02 22:22:39 UTC (rev 94456)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-09-02 22:32:44 UTC (rev 94457)
@@ -1,3 +1,21 @@
+2011-08-30 Matthew Delaney <[email protected]>
+
+ Read out of bounds in sUnpremultiplyData_RGBA8888 / ImageBufferData::getData
+ https://bugs.webkit.org/show_bug.cgi?id=65352
+
+ Reviewed by Simon Fraser.
+
+ New test: fast/canvas/canvas-getImageData-large-crash.html
+
+ This patch prevents overflows from happening in getImageData, createImageData, and canvas creation
+ calls that specify widths and heights that end up overflowing the ints that we store those values in
+ as well as derived values such as area and maxX / maxY of the bounding rects involved. Overflow of integer
+ arithmetic is detected via the use of the new Checked type that was introduced in r94207. The change to JSC
+ is just to add a new helper method described below.
+
+ * wtf/MathExtras.h:
+ (isWithinIntRange): Reports if a float's value is within the range expressible by an int.
+
2011-09-02 Mark Hahnenberg <[email protected]>
Incorporate newer, faster dtoa library
Modified: trunk/Source/_javascript_Core/wtf/MathExtras.h (94456 => 94457)
--- trunk/Source/_javascript_Core/wtf/MathExtras.h 2011-09-02 22:22:39 UTC (rev 94456)
+++ trunk/Source/_javascript_Core/wtf/MathExtras.h 2011-09-02 22:32:44 UTC (rev 94457)
@@ -254,6 +254,11 @@
return static_cast<int>(x);
}
+inline bool isWithinIntRange(float x)
+{
+ return x > static_cast<float>(std::numeric_limits<int>::min()) && x < static_cast<float>(std::numeric_limits<int>::max());
+}
+
#if !COMPILER(MSVC) && !(COMPILER(RVCT) && PLATFORM(BREWMP)) && !OS(SOLARIS) && !OS(SYMBIAN)
using std::isfinite;
using std::isinf;
Modified: trunk/Source/WebCore/ChangeLog (94456 => 94457)
--- trunk/Source/WebCore/ChangeLog 2011-09-02 22:22:39 UTC (rev 94456)
+++ trunk/Source/WebCore/ChangeLog 2011-09-02 22:32:44 UTC (rev 94457)
@@ -1,3 +1,36 @@
+2011-08-30 Matthew Delaney <[email protected]>
+
+ Read out of bounds in sUnpremultiplyData_RGBA8888 / ImageBufferData::getData
+ https://bugs.webkit.org/show_bug.cgi?id=65352
+
+ Reviewed by Simon Fraser.
+
+ New test: fast/canvas/canvas-getImageData-large-crash.html
+
+ This patch prevents overflows from happening in getImageData, createImageData, and canvas creation
+ calls that specify widths and heights that end up overflowing the ints that we store those values in
+ as well as derived values such as area and maxX / maxY of the bounding rects involved. Overflow of integer
+ arithmetic is detected via the use of the new Checked type that was introduced in r94207.
+
+ * html/HTMLCanvasElement.cpp:
+ (WebCore::HTMLCanvasElement::convertLogicalToDevice): Removed dependency on ints, using FloatRects/Sizes instead.
+ (WebCore::HTMLCanvasElement::createImageBuffer): Moved the check for max canvas area and dimensions here.
+ Added in check that prevents us from having canvases of sizes that will cause overflows.
+ (WebCore::HTMLCanvasElement::baseTransform): Updated use of convertLogicalToDevice.
+ * html/HTMLCanvasElement.h: Updated method signatures.
+ * html/canvas/CanvasRenderingContext2D.cpp:
+ (WebCore::createEmptyImageData): Added in check to prevent creating ImageData objects that will cause overflow when computing their size.
+ (WebCore::CanvasRenderingContext2D::createImageData): Avoid creating ImageData objects of size that will overflow later.
+ (WebCore::CanvasRenderingContext2D::getImageData): Added in check to prevent trying to get ImageData objects that will cause overflow when computing their size.
+ * platform/graphics/FloatRect.cpp:
+ (WebCore::FloatRect::isExpressibleAsIntRect): New method that tests whether a FloatRect can become an IntRect without overflow or having to be clamped.
+ * platform/graphics/FloatRect.h:
+ * platform/graphics/FloatSize.cpp:
+ (WebCore::FloatSize::isExpressibleAsIntSize): Same as FloatRect, but for FloatSize->IntSize.
+ * platform/graphics/FloatSize.h:
+ * platform/graphics/cg/ImageBufferCG.cpp: Added check for overflow.
+ (WebCore::ImageBuffer::ImageBuffer):
+
2011-09-02 Dan Bernstein <[email protected]>
<rdar://problem/9755843> anonymous RenderMathMLOperator sets itself as the renderer of its parent mfenced node
Modified: trunk/Source/WebCore/html/HTMLCanvasElement.cpp (94456 => 94457)
--- trunk/Source/WebCore/html/HTMLCanvasElement.cpp 2011-09-02 22:22:39 UTC (rev 94456)
+++ trunk/Source/WebCore/html/HTMLCanvasElement.cpp 2011-09-02 22:32:44 UTC (rev 94457)
@@ -371,39 +371,28 @@
#endif
}
-IntRect HTMLCanvasElement::convertLogicalToDevice(const FloatRect& logicalRect) const
+FloatRect HTMLCanvasElement::convertLogicalToDevice(const FloatRect& logicalRect) const
{
- // Prevent under/overflow by ensuring the rect's bounds stay within integer-expressible range
- int left = clampToInteger(floorf(logicalRect.x() * m_deviceScaleFactor));
- int top = clampToInteger(floorf(logicalRect.y() * m_deviceScaleFactor));
- int right = clampToInteger(ceilf(logicalRect.maxX() * m_deviceScaleFactor));
- int bottom = clampToInteger(ceilf(logicalRect.maxY() * m_deviceScaleFactor));
+ FloatRect deviceRect(logicalRect);
+ deviceRect.scale(m_deviceScaleFactor);
- return IntRect(IntPoint(left, top), convertToValidDeviceSize(right - left, bottom - top));
-}
+ float x = floorf(deviceRect.x());
+ float y = floorf(deviceRect.y());
+ float w = ceilf(deviceRect.maxX() - x);
+ float h = ceilf(deviceRect.maxY() - y);
+ deviceRect.setX(x);
+ deviceRect.setY(y);
+ deviceRect.setWidth(w);
+ deviceRect.setHeight(h);
-IntSize HTMLCanvasElement::convertLogicalToDevice(const FloatSize& logicalSize) const
-{
- // Prevent overflow by ensuring the rect's bounds stay within integer-expressible range
- float width = clampToInteger(ceilf(logicalSize.width() * m_deviceScaleFactor));
- float height = clampToInteger(ceilf(logicalSize.height() * m_deviceScaleFactor));
- return convertToValidDeviceSize(width, height);
+ return deviceRect;
}
-IntSize HTMLCanvasElement::convertToValidDeviceSize(float width, float height) const
+FloatSize HTMLCanvasElement::convertLogicalToDevice(const FloatSize& logicalSize) const
{
- width = ceilf(width);
- height = ceilf(height);
-
- if (width < 1 || height < 1 || width * height > MaxCanvasArea)
- return IntSize();
-
-#if USE(SKIA)
- if (width > MaxSkiaDim || height > MaxSkiaDim)
- return IntSize();
-#endif
-
- return IntSize(width, height);
+ float width = ceilf(logicalSize.width() * m_deviceScaleFactor);
+ float height = ceilf(logicalSize.height() * m_deviceScaleFactor);
+ return FloatSize(width, height);
}
SecurityOrigin* HTMLCanvasElement::securityOrigin() const
@@ -446,18 +435,27 @@
m_hasCreatedImageBuffer = true;
- FloatSize unscaledSize(width(), height());
- IntSize size = convertLogicalToDevice(unscaledSize);
- if (!size.width() || !size.height())
+ FloatSize logicalSize(width(), height());
+ FloatSize deviceSize = convertLogicalToDevice(logicalSize);
+ if (!deviceSize.isExpressibleAsIntSize())
return;
- RenderingMode renderingMode = shouldAccelerate(size) ? Accelerated : Unaccelerated;
- m_imageBuffer = ImageBuffer::create(size, ColorSpaceDeviceRGB, renderingMode);
- // The convertLogicalToDevice MaxCanvasArea check should prevent common cases
- // where ImageBuffer::create() returns 0, however we could still be low on memory.
+ if (deviceSize.width() * deviceSize.height() > MaxCanvasArea)
+ return;
+#if USE(SKIA)
+ if (deviceSize.width() > MaxSkiaDim || deviceSize.height() > MaxSkiaDim)
+ return;
+#endif
+
+ IntSize bufferSize(deviceSize.width(), deviceSize.height());
+ if (!bufferSize.width() || !bufferSize.height())
+ return;
+
+ RenderingMode renderingMode = shouldAccelerate(bufferSize) ? Accelerated : Unaccelerated;
+ m_imageBuffer = ImageBuffer::create(bufferSize, ColorSpaceDeviceRGB, renderingMode);
if (!m_imageBuffer)
return;
- m_imageBuffer->context()->scale(FloatSize(size.width() / unscaledSize.width(), size.height() / unscaledSize.height()));
+ m_imageBuffer->context()->scale(FloatSize(bufferSize.width() / logicalSize.width(), bufferSize.height() / logicalSize.height()));
m_imageBuffer->context()->setShadowsIgnoreTransforms(true);
m_imageBuffer->context()->setImageInterpolationQuality(DefaultInterpolationQuality);
@@ -512,7 +510,8 @@
{
ASSERT(m_hasCreatedImageBuffer);
FloatSize unscaledSize(width(), height());
- IntSize size = convertLogicalToDevice(unscaledSize);
+ FloatSize deviceSize = convertLogicalToDevice(unscaledSize);
+ IntSize size(deviceSize.width(), deviceSize.height());
AffineTransform transform;
if (size.width() && size.height())
transform.scaleNonUniform(size.width() / unscaledSize.width(), size.height() / unscaledSize.height());
Modified: trunk/Source/WebCore/html/HTMLCanvasElement.h (94456 => 94457)
--- trunk/Source/WebCore/html/HTMLCanvasElement.h 2011-09-02 22:22:39 UTC (rev 94456)
+++ trunk/Source/WebCore/html/HTMLCanvasElement.h 2011-09-02 22:32:44 UTC (rev 94457)
@@ -111,9 +111,8 @@
void makePresentationCopy();
void clearPresentationCopy();
- IntRect convertLogicalToDevice(const FloatRect&) const;
- IntSize convertLogicalToDevice(const FloatSize&) const;
- IntSize convertToValidDeviceSize(float width, float height) const;
+ FloatRect convertLogicalToDevice(const FloatRect&) const;
+ FloatSize convertLogicalToDevice(const FloatSize&) const;
SecurityOrigin* securityOrigin() const;
void setOriginTainted() { m_originClean = false; }
Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp (94456 => 94457)
--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp 2011-09-02 22:22:39 UTC (rev 94456)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp 2011-09-02 22:32:44 UTC (rev 94457)
@@ -66,6 +66,7 @@
#endif
#include <wtf/ByteArray.h>
+#include <wtf/CheckedArithmetic.h>
#include <wtf/MathExtras.h>
#include <wtf/OwnPtr.h>
#include <wtf/UnusedParam.h>
@@ -1660,6 +1661,12 @@
static PassRefPtr<ImageData> createEmptyImageData(const IntSize& size)
{
+ Checked<int, RecordOverflow> dataSize = 4;
+ dataSize *= size.width();
+ dataSize *= size.height();
+ if (dataSize.hasOverflowed())
+ return 0;
+
RefPtr<ImageData> data = ""
memset(data->data()->data()->data(), 0, data->data()->data()->length());
return data.release();
@@ -1687,18 +1694,18 @@
return 0;
}
- FloatSize unscaledSize(fabs(sw), fabs(sh));
- IntSize scaledSize = canvas()->convertLogicalToDevice(unscaledSize);
- if (scaledSize.width() < 1)
- scaledSize.setWidth(1);
- if (scaledSize.height() < 1)
- scaledSize.setHeight(1);
-
- float area = 4.0f * scaledSize.width() * scaledSize.height();
- if (area > static_cast<float>(std::numeric_limits<int>::max()))
+ FloatSize logicalSize(fabs(sw), fabs(sh));
+ FloatSize deviceSize = canvas()->convertLogicalToDevice(logicalSize);
+ if (!deviceSize.isExpressibleAsIntSize())
return 0;
- return createEmptyImageData(scaledSize);
+ IntSize size(deviceSize.width(), deviceSize.height());
+ if (size.width() < 1)
+ size.setWidth(1);
+ if (size.height() < 1)
+ size.setHeight(1);
+
+ return createEmptyImageData(size);
}
PassRefPtr<ImageData> CanvasRenderingContext2D::getImageData(float sx, float sy, float sw, float sh, ExceptionCode& ec) const
@@ -1725,21 +1732,25 @@
sh = -sh;
}
- FloatRect unscaledRect(sx, sy, sw, sh);
- IntRect scaledRect = canvas()->convertLogicalToDevice(unscaledRect);
- if (scaledRect.width() < 1)
- scaledRect.setWidth(1);
- if (scaledRect.height() < 1)
- scaledRect.setHeight(1);
+ FloatRect logicalRect(sx, sy, sw, sh);
+ FloatRect deviceRect = canvas()->convertLogicalToDevice(logicalRect);
+ if (deviceRect.width() < 1)
+ deviceRect.setWidth(1);
+ if (deviceRect.height() < 1)
+ deviceRect.setHeight(1);
+ if (!deviceRect.isExpressibleAsIntRect())
+ return 0;
+
+ IntRect imageDataRect(deviceRect);
ImageBuffer* buffer = canvas()->buffer();
if (!buffer)
- return createEmptyImageData(scaledRect.size());
+ return createEmptyImageData(imageDataRect.size());
- RefPtr<ByteArray> byteArray = buffer->getUnmultipliedImageData(scaledRect);
+ RefPtr<ByteArray> byteArray = buffer->getUnmultipliedImageData(imageDataRect);
if (!byteArray)
return 0;
- return ImageData::create(scaledRect.size(), byteArray.release());
+ return ImageData::create(imageDataRect.size(), byteArray.release());
}
void CanvasRenderingContext2D::putImageData(ImageData* data, float dx, float dy, ExceptionCode& ec)
Modified: trunk/Source/WebCore/platform/graphics/FloatRect.cpp (94456 => 94457)
--- trunk/Source/WebCore/platform/graphics/FloatRect.cpp 2011-09-02 22:22:39 UTC (rev 94456)
+++ trunk/Source/WebCore/platform/graphics/FloatRect.cpp 2011-09-02 22:32:44 UTC (rev 94457)
@@ -47,6 +47,13 @@
return FloatRect(narrowPrecisionToFloat(x), narrowPrecisionToFloat(y), narrowPrecisionToFloat(width), narrowPrecisionToFloat(height));
}
+bool FloatRect::isExpressibleAsIntRect() const
+{
+ return isWithinIntRange(x()) && isWithinIntRange(y())
+ && isWithinIntRange(width()) && isWithinIntRange(height())
+ && isWithinIntRange(maxX()) && isWithinIntRange(maxY());
+}
+
bool FloatRect::intersects(const FloatRect& other) const
{
// Checking emptiness handles negative widths as well as zero.
Modified: trunk/Source/WebCore/platform/graphics/FloatRect.h (94456 => 94457)
--- trunk/Source/WebCore/platform/graphics/FloatRect.h 2011-09-02 22:22:39 UTC (rev 94456)
+++ trunk/Source/WebCore/platform/graphics/FloatRect.h 2011-09-02 22:32:44 UTC (rev 94457)
@@ -103,6 +103,7 @@
bool isEmpty() const { return m_size.isEmpty(); }
bool isZero() const { return m_size.isZero(); }
+ bool isExpressibleAsIntRect() const;
FloatPoint center() const { return FloatPoint(x() + width() / 2, y() + height() / 2); }
Modified: trunk/Source/WebCore/platform/graphics/FloatSize.cpp (94456 => 94457)
--- trunk/Source/WebCore/platform/graphics/FloatSize.cpp 2011-09-02 22:22:39 UTC (rev 94456)
+++ trunk/Source/WebCore/platform/graphics/FloatSize.cpp 2011-09-02 22:32:44 UTC (rev 94457)
@@ -50,6 +50,11 @@
return fabs(m_width) < numeric_limits<float>::epsilon() && fabs(m_height) < numeric_limits<float>::epsilon();
}
+bool FloatSize::isExpressibleAsIntSize() const
+{
+ return isWithinIntRange(m_width) && isWithinIntRange(m_height);
+}
+
FloatSize FloatSize::narrowPrecision(double width, double height)
{
return FloatSize(narrowPrecisionToFloat(width), narrowPrecisionToFloat(height));
Modified: trunk/Source/WebCore/platform/graphics/FloatSize.h (94456 => 94457)
--- trunk/Source/WebCore/platform/graphics/FloatSize.h 2011-09-02 22:22:39 UTC (rev 94456)
+++ trunk/Source/WebCore/platform/graphics/FloatSize.h 2011-09-02 22:32:44 UTC (rev 94457)
@@ -63,6 +63,7 @@
bool isEmpty() const { return m_width <= 0 || m_height <= 0; }
bool isZero() const;
+ bool isExpressibleAsIntSize() const;
float aspectRatio() const { return m_width / m_height; }
Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp (94456 => 94457)
--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp 2011-09-02 22:22:39 UTC (rev 94456)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp 2011-09-02 22:32:44 UTC (rev 94457)
@@ -37,6 +37,7 @@
#include <ApplicationServices/ApplicationServices.h>
#include <math.h>
#include <wtf/Assertions.h>
+#include <wtf/CheckedArithmetic.h>
#include <wtf/MainThread.h>
#include <wtf/OwnArrayPtr.h>
#include <wtf/RetainPtr.h>
@@ -108,22 +109,25 @@
, m_accelerateRendering(renderingMode == Accelerated)
{
success = false; // Make early return mean failure.
- if (size.width() < 0 || size.height() < 0)
+ if (size.width() <= 0 || size.height() <= 0)
return;
+
+ Checked<int, RecordOverflow> width = size.width();
+ Checked<int, RecordOverflow> height = size.height();
+
+ // Prevent integer overflows
+ m_data.m_bytesPerRow = 4 * width;
+ Checked<size_t, RecordOverflow> dataSize = height * m_data.m_bytesPerRow;
+ if (dataSize.hasOverflowed())
+ return;
+
#if USE(IOSURFACE_CANVAS_BACKING_STORE)
- if (size.width() >= maxIOSurfaceDimension || size.height() >= maxIOSurfaceDimension || size.width() * size.height() < minIOSurfaceArea)
+ if (width.unsafeGet() >= maxIOSurfaceDimension || height.unsafeGet() >= maxIOSurfaceDimension || (width * height).unsafeGet() < minIOSurfaceArea)
m_accelerateRendering = false;
#else
ASSERT(renderingMode == Unaccelerated);
#endif
- unsigned bytesPerRow = size.width();
- if (bytesPerRow > 0x3FFFFFFF) // Protect against overflow
- return;
- bytesPerRow *= 4;
- m_data.m_bytesPerRow = bytesPerRow;
- size_t dataSize = size.height() * bytesPerRow;
-
switch (imageColorSpace) {
case ColorSpaceDeviceRGB:
m_data.m_colorSpace = deviceRGBColorSpaceRef();
@@ -140,21 +144,21 @@
if (m_accelerateRendering) {
#if USE(IOSURFACE_CANVAS_BACKING_STORE)
m_data.m_surface = createIOSurface(size);
- cgContext.adoptCF(wkIOSurfaceContextCreate(m_data.m_surface.get(), size.width(), size.height(), m_data.m_colorSpace));
+ cgContext.adoptCF(wkIOSurfaceContextCreate(m_data.m_surface.get(), width.unsafeGet(), height.unsafeGet(), m_data.m_colorSpace));
#endif
if (!cgContext)
m_accelerateRendering = false; // If allocation fails, fall back to non-accelerated path.
}
if (!m_accelerateRendering) {
- if (!tryFastCalloc(size.height(), bytesPerRow).getValue(m_data.m_data))
+ if (!tryFastCalloc(height.unsafeGet(), m_data.m_bytesPerRow.unsafeGet()).getValue(m_data.m_data))
return;
ASSERT(!(reinterpret_cast<size_t>(m_data.m_data) & 2));
m_data.m_bitmapInfo = kCGImageAlphaPremultipliedLast;
- cgContext.adoptCF(CGBitmapContextCreate(m_data.m_data, size.width(), size.height(), 8, bytesPerRow, m_data.m_colorSpace, m_data.m_bitmapInfo));
+ cgContext.adoptCF(CGBitmapContextCreate(m_data.m_data, width.unsafeGet(), height.unsafeGet(), 8, m_data.m_bytesPerRow.unsafeGet(), m_data.m_colorSpace, m_data.m_bitmapInfo));
// Create a live image that wraps the data.
- m_data.m_dataProvider.adoptCF(CGDataProviderCreateWithData(0, m_data.m_data, dataSize, releaseImageData));
+ m_data.m_dataProvider.adoptCF(CGDataProviderCreateWithData(0, m_data.m_data, dataSize.unsafeGet(), releaseImageData));
}
if (!cgContext)
@@ -162,7 +166,7 @@
m_context= adoptPtr(new GraphicsContext(cgContext.get()));
m_context->scale(FloatSize(1, -1));
- m_context->translate(0, -size.height());
+ m_context->translate(0, -height.unsafeGet());
success = true;
}
@@ -172,7 +176,7 @@
size_t ImageBuffer::dataSize() const
{
- return m_size.height() * m_data.m_bytesPerRow;
+ return m_size.height() * m_data.m_bytesPerRow.unsafeGet();
}
GraphicsContext* ImageBuffer::context() const
@@ -196,7 +200,7 @@
if (!m_accelerateRendering) {
switch (copyBehavior) {
case DontCopyBackingStore:
- image = CGImageCreate(m_size.width(), m_size.height(), 8, 32, m_data.m_bytesPerRow, m_data.m_colorSpace, m_data.m_bitmapInfo, m_data.m_dataProvider.get(), 0, true, kCGRenderingIntentDefault);
+ image = CGImageCreate(m_size.width(), m_size.height(), 8, 32, m_data.m_bytesPerRow.unsafeGet(), m_data.m_colorSpace, m_data.m_bitmapInfo, m_data.m_dataProvider.get(), 0, true, kCGRenderingIntentDefault);
break;
case CopyBackingStore:
image = CGBitmapContextCreateImage(context()->platformContext());
Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.h (94456 => 94457)
--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.h 2011-09-02 22:22:39 UTC (rev 94456)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.h 2011-09-02 22:32:44 UTC (rev 94457)
@@ -26,6 +26,7 @@
#include "Image.h"
#include <wtf/ByteArray.h>
+#include <wtf/CheckedArithmetic.h>
#include <wtf/RefPtr.h>
#include <wtf/RetainPtr.h>
@@ -50,7 +51,7 @@
RetainPtr<CGDataProviderRef> m_dataProvider;
CGBitmapInfo m_bitmapInfo;
- unsigned m_bytesPerRow;
+ Checked<unsigned, RecordOverflow> m_bytesPerRow;
CGColorSpaceRef m_colorSpace;
RetainPtr<IOSurfaceRef> m_surface;