Title: [94457] trunk
Revision
94457
Author
[email protected]
Date
2011-09-02 15:32:44 -0700 (Fri, 02 Sep 2011)

Log Message

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

Source/_javascript_Core: 

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.

Source/WebCore: 

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):

Modified Paths

Added Paths

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;
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to