Diff
Added: branches/safari-534.54-branch/LayoutTests/fast/canvas/canvas-getImageData-large-crash-expected.txt (0 => 104100)
--- branches/safari-534.54-branch/LayoutTests/fast/canvas/canvas-getImageData-large-crash-expected.txt (rev 0)
+++ branches/safari-534.54-branch/LayoutTests/fast/canvas/canvas-getImageData-large-crash-expected.txt 2012-01-05 01:04:36 UTC (rev 104100)
@@ -0,0 +1 @@
+PASSED (If this page did not crash.)
Added: branches/safari-534.54-branch/LayoutTests/fast/canvas/canvas-getImageData-large-crash.html (0 => 104100)
--- branches/safari-534.54-branch/LayoutTests/fast/canvas/canvas-getImageData-large-crash.html (rev 0)
+++ branches/safari-534.54-branch/LayoutTests/fast/canvas/canvas-getImageData-large-crash.html 2012-01-05 01:04:36 UTC (rev 104100)
@@ -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: branches/safari-534.54-branch/Source/_javascript_Core/ChangeLog (104099 => 104100)
--- branches/safari-534.54-branch/Source/_javascript_Core/ChangeLog 2012-01-05 01:01:16 UTC (rev 104099)
+++ branches/safari-534.54-branch/Source/_javascript_Core/ChangeLog 2012-01-05 01:04:36 UTC (rev 104100)
@@ -1,3 +1,25 @@
+2012-01-04 Oliver Hunt <[email protected]>
+
+ Merge r94457
+
+ 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-12-22 Oliver Hunt <[email protected]>
Merge 103218
Modified: branches/safari-534.54-branch/Source/WebCore/ChangeLog (104099 => 104100)
--- branches/safari-534.54-branch/Source/WebCore/ChangeLog 2012-01-05 01:01:16 UTC (rev 104099)
+++ branches/safari-534.54-branch/Source/WebCore/ChangeLog 2012-01-05 01:04:36 UTC (rev 104100)
@@ -1,3 +1,40 @@
+2012-01-04 Oliver Hunt <[email protected]>
+
+ Merge r94457
+
+ 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-1-4 Lucas Forschler <[email protected]>
Merge 97124
Modified: branches/safari-534.54-branch/Source/WebCore/html/HTMLCanvasElement.cpp (104099 => 104100)
--- branches/safari-534.54-branch/Source/WebCore/html/HTMLCanvasElement.cpp 2012-01-05 01:01:16 UTC (rev 104099)
+++ branches/safari-534.54-branch/Source/WebCore/html/HTMLCanvasElement.cpp 2012-01-05 01:04:36 UTC (rev 104100)
@@ -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);
}
const SecurityOrigin& HTMLCanvasElement::securityOrigin() const
@@ -416,30 +405,57 @@
return document()->styleSelector();
}
+bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const
+{
+#if USE(IOSURFACE_CANVAS_BACKING_STORE)
+ UNUSED_PARAM(size);
+ return document()->settings()->canvasUsesAcceleratedDrawing();
+#elif ENABLE(ACCELERATED_2D_CANVAS)
+ if (m_context && !m_context->is2d())
+ return false;
+
+ Settings* settings = document()->settings();
+ if (!settings->accelerated2dCanvasEnabled())
+ return false;
+
+ // Do not use acceleration for small canvas.
+ if (size.width() * size.height() < settings->minimumAccelerated2dCanvasSize())
+ return false;
+
+ return true;
+#else
+ UNUSED_PARAM(size);
+ return false;
+#endif
+}
+
void HTMLCanvasElement::createImageBuffer() const
{
ASSERT(!m_imageBuffer);
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;
-#if USE(IOSURFACE_CANVAS_BACKING_STORE)
- if (document()->settings()->canvasUsesAcceleratedDrawing())
- m_imageBuffer = ImageBuffer::create(size, ColorSpaceDeviceRGB, Accelerated);
- else
- m_imageBuffer = ImageBuffer::create(size, ColorSpaceDeviceRGB, Unaccelerated);
-#else
- m_imageBuffer = ImageBuffer::create(size);
+ if (deviceSize.width() * deviceSize.height() > MaxCanvasArea)
+ return;
+#if USE(SKIA)
+ if (deviceSize.width() > MaxSkiaDim || deviceSize.height() > MaxSkiaDim)
+ return;
#endif
- // The convertLogicalToDevice MaxCanvasArea check should prevent common cases
- // where ImageBuffer::create() returns 0, however we could still be low on memory.
+
+ 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);
@@ -488,7 +504,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: branches/safari-534.54-branch/Source/WebCore/html/HTMLCanvasElement.h (104099 => 104100)
--- branches/safari-534.54-branch/Source/WebCore/html/HTMLCanvasElement.h 2012-01-05 01:01:16 UTC (rev 104099)
+++ branches/safari-534.54-branch/Source/WebCore/html/HTMLCanvasElement.h 2012-01-05 01:04:36 UTC (rev 104100)
@@ -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;
const SecurityOrigin& securityOrigin() const;
void setOriginTainted() { m_originClean = false; }
@@ -141,6 +140,7 @@
void setSurfaceSize(const IntSize&);
bool hasCreatedImageBuffer() const { return m_hasCreatedImageBuffer; }
+ bool shouldAccelerate(const IntSize&) const;
HashSet<CanvasObserver*> m_observers;
Modified: branches/safari-534.54-branch/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp (104099 => 104100)
--- branches/safari-534.54-branch/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp 2012-01-05 01:01:16 UTC (rev 104099)
+++ branches/safari-534.54-branch/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp 2012-01-05 01:04:36 UTC (rev 104100)
@@ -74,6 +74,7 @@
#endif
#include <wtf/ByteArray.h>
+#include <wtf/CheckedArithmetic.h>
#include <wtf/MathExtras.h>
#include <wtf/OwnPtr.h>
#include <wtf/UnusedParam.h>
@@ -1623,6 +1624,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();
@@ -1650,18 +1657,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
@@ -1688,21 +1695,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: branches/safari-534.54-branch/Source/WebCore/platform/graphics/FloatRect.cpp (104099 => 104100)
--- branches/safari-534.54-branch/Source/WebCore/platform/graphics/FloatRect.cpp 2012-01-05 01:01:16 UTC (rev 104099)
+++ branches/safari-534.54-branch/Source/WebCore/platform/graphics/FloatRect.cpp 2012-01-05 01:04:36 UTC (rev 104100)
@@ -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: branches/safari-534.54-branch/Source/WebCore/platform/graphics/FloatRect.h (104099 => 104100)
--- branches/safari-534.54-branch/Source/WebCore/platform/graphics/FloatRect.h 2012-01-05 01:01:16 UTC (rev 104099)
+++ branches/safari-534.54-branch/Source/WebCore/platform/graphics/FloatRect.h 2012-01-05 01:04:36 UTC (rev 104100)
@@ -101,6 +101,8 @@
void setHeight(float height) { m_size.setHeight(height); }
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: branches/safari-534.54-branch/Source/WebCore/platform/graphics/FloatSize.cpp (104099 => 104100)
--- branches/safari-534.54-branch/Source/WebCore/platform/graphics/FloatSize.cpp 2012-01-05 01:01:16 UTC (rev 104099)
+++ branches/safari-534.54-branch/Source/WebCore/platform/graphics/FloatSize.cpp 2012-01-05 01:04:36 UTC (rev 104100)
@@ -29,8 +29,11 @@
#include "FloatConversion.h"
#include "IntSize.h"
+#include <limits>
#include <math.h>
+using namespace std;
+
namespace WebCore {
FloatSize::FloatSize(const IntSize& size) : m_width(size.width()), m_height(size.height())
@@ -42,6 +45,16 @@
return sqrtf(diagonalLengthSquared());
}
+bool FloatSize::isZero() const
+{
+ 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: branches/safari-534.54-branch/Source/WebCore/platform/graphics/FloatSize.h (104099 => 104100)
--- branches/safari-534.54-branch/Source/WebCore/platform/graphics/FloatSize.h 2012-01-05 01:01:16 UTC (rev 104099)
+++ branches/safari-534.54-branch/Source/WebCore/platform/graphics/FloatSize.h 2012-01-05 01:04:36 UTC (rev 104100)
@@ -62,6 +62,8 @@
void setHeight(float height) { m_height = height; }
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: branches/safari-534.54-branch/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp (104099 => 104100)
--- branches/safari-534.54-branch/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp 2012-01-05 01:01:16 UTC (rev 104099)
+++ branches/safari-534.54-branch/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp 2012-01-05 01:04:36 UTC (rev 104100)
@@ -36,6 +36,7 @@
#include "MIMETypeRegistry.h"
#include <ApplicationServices/ApplicationServices.h>
#include <wtf/Assertions.h>
+#include <wtf/CheckedArithmetic.h>
#include <wtf/CurrentTime.h>
#include <wtf/text/WTFString.h>
#include <wtf/OwnArrayPtr.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();
@@ -137,22 +141,24 @@
}
RetainPtr<CGContextRef> cgContext;
+ if (m_accelerateRendering) {
+#if USE(IOSURFACE_CANVAS_BACKING_STORE)
+ m_data.m_surface = createIOSurface(size);
+ 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));
- } else {
-#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));
-#else
- m_accelerateRendering = false; // Force to false on older platforms
-#endif
+ m_data.m_dataProvider.adoptCF(CGDataProviderCreateWithData(0, m_data.m_data, dataSize.unsafeGet(), releaseImageData));
}
if (!cgContext)
@@ -160,8 +166,7 @@
m_context = adoptPtr(new GraphicsContext(cgContext.get()));
m_context->scale(FloatSize(1, -1));
- m_context->translate(0, -size.height());
- m_data.m_lastFlushTime = currentTimeMS();
+ m_context->translate(0, -height.unsafeGet());
success = true;
}
@@ -171,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
@@ -213,7 +218,7 @@
static CGImageRef cgImage(const IntSize& size, const ImageBufferData& data)
{
- return CGImageCreate(size.width(), size.height(), 8, 32, data.m_bytesPerRow,
+ return CGImageCreate(size.width(), size.height(), 8, 32, data.m_bytesPerRow.unsafeGet(),
data.m_colorSpace, data.m_bitmapInfo, data.m_dataProvider.get(), 0, true, kCGRenderingIntentDefault);
}
Modified: branches/safari-534.54-branch/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.h (104099 => 104100)
--- branches/safari-534.54-branch/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.h 2012-01-05 01:01:16 UTC (rev 104099)
+++ branches/safari-534.54-branch/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.h 2012-01-05 01:04:36 UTC (rev 104100)
@@ -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;
mutable double m_lastFlushTime;