Title: [95080] trunk
Revision
95080
Author
commit-qu...@webkit.org
Date
2011-09-14 01:10:05 -0700 (Wed, 14 Sep 2011)

Log Message

Large canvas fills should not crash or create unnecessarily large image buffers
https://bugs.webkit.org/show_bug.cgi?id=67988

Source/WebCore:

When using source-in, destination-in, source-out, or destination-atop a temporary
buffer is created. This buffer only needs to be big enough to cover the intersection
of the path and the canvas.

This change also adds some null checks for failures to create contexts or buffers.

Patch by Ben Wells <benwe...@chromium.org> on 2011-09-14
Reviewed by Stephen White.

Test: fast/canvas/canvas-large-fills.html

* html/canvas/CanvasRenderingContext2D.cpp:
(WebCore::CanvasRenderingContext2D::clearCanvas):
(WebCore::CanvasRenderingContext2D::fillAndDisplayTransparencyElsewhere):

LayoutTests:

Patch by Ben Wells <benwe...@chromium.org> on 2011-09-14
Reviewed by Stephen White.

* fast/canvas/canvas-large-fills-expected.txt: Added.
* fast/canvas/canvas-large-fills.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (95079 => 95080)


--- trunk/LayoutTests/ChangeLog	2011-09-14 07:40:25 UTC (rev 95079)
+++ trunk/LayoutTests/ChangeLog	2011-09-14 08:10:05 UTC (rev 95080)
@@ -1,3 +1,13 @@
+2011-09-14  Ben Wells  <benwe...@chromium.org>
+
+        Large canvas fills should not crash or create unnecessarily large image buffers
+        https://bugs.webkit.org/show_bug.cgi?id=67988
+
+        Reviewed by Stephen White.
+
+        * fast/canvas/canvas-large-fills-expected.txt: Added.
+        * fast/canvas/canvas-large-fills.html: Added.
+
 2011-09-14  Kentaro Hara  <hara...@google.com>
 
         Implement a PageTransitionEvent constructor for JSC

Added: trunk/LayoutTests/fast/canvas/canvas-large-fills-expected.txt (0 => 95080)


--- trunk/LayoutTests/fast/canvas/canvas-large-fills-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/canvas/canvas-large-fills-expected.txt	2011-09-14 08:10:05 UTC (rev 95080)
@@ -0,0 +1,138 @@
+Tests that using the different composite modes to fill large rects doesn't crash and works as expected.
+
+size == 10000
+source-over
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+PASS Actual: 255 Expected: 255
+source-in
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+PASS Actual: 255 Expected: 255
+source-out
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+source-atop
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+PASS Actual: 255 Expected: 255
+destination-over
+PASS Actual: 0 Expected: 0
+PASS Actual: 255 Expected: 255
+PASS Actual: 0 Expected: 0
+destination-in
+PASS Actual: 0 Expected: 0
+PASS Actual: 255 Expected: 255
+PASS Actual: 0 Expected: 0
+destination-out
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+destination-atop
+PASS Actual: 0 Expected: 0
+PASS Actual: 255 Expected: 255
+PASS Actual: 0 Expected: 0
+lighter
+PASS Actual: 0 Expected: 0
+PASS Actual: 255 Expected: 255
+PASS Actual: 255 Expected: 255
+copy
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+PASS Actual: 255 Expected: 255
+xor
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+size == 50000
+source-over
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+PASS Actual: 255 Expected: 255
+source-in
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+PASS Actual: 255 Expected: 255
+source-out
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+source-atop
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+PASS Actual: 255 Expected: 255
+destination-over
+PASS Actual: 0 Expected: 0
+PASS Actual: 255 Expected: 255
+PASS Actual: 0 Expected: 0
+destination-in
+PASS Actual: 0 Expected: 0
+PASS Actual: 255 Expected: 255
+PASS Actual: 0 Expected: 0
+destination-out
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+destination-atop
+PASS Actual: 0 Expected: 0
+PASS Actual: 255 Expected: 255
+PASS Actual: 0 Expected: 0
+lighter
+PASS Actual: 0 Expected: 0
+PASS Actual: 255 Expected: 255
+PASS Actual: 255 Expected: 255
+copy
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+PASS Actual: 255 Expected: 255
+xor
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+size == 100000
+source-over
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+PASS Actual: 255 Expected: 255
+source-in
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+PASS Actual: 255 Expected: 255
+source-out
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+source-atop
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+PASS Actual: 255 Expected: 255
+destination-over
+PASS Actual: 0 Expected: 0
+PASS Actual: 255 Expected: 255
+PASS Actual: 0 Expected: 0
+destination-in
+PASS Actual: 0 Expected: 0
+PASS Actual: 255 Expected: 255
+PASS Actual: 0 Expected: 0
+destination-out
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+destination-atop
+PASS Actual: 0 Expected: 0
+PASS Actual: 255 Expected: 255
+PASS Actual: 0 Expected: 0
+lighter
+PASS Actual: 0 Expected: 0
+PASS Actual: 255 Expected: 255
+PASS Actual: 255 Expected: 255
+copy
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+PASS Actual: 255 Expected: 255
+xor
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+PASS Actual: 0 Expected: 0
+

Added: trunk/LayoutTests/fast/canvas/canvas-large-fills.html (0 => 95080)


--- trunk/LayoutTests/fast/canvas/canvas-large-fills.html	                        (rev 0)
+++ trunk/LayoutTests/fast/canvas/canvas-large-fills.html	2011-09-14 08:10:05 UTC (rev 95080)
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<title>Canvas test: test large width/height values</title>
+<script src=""
+<body>
+<p>Tests that using the different composite modes to fill large rects doesn't crash and works as expected.</p>
+<pre id="console"></pre>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<script>
+var canvas = document.getElementById("c");
+var ctx = canvas.getContext("2d");
+var x, y, w=1, h=1;
+var width=canvas.width;
+var height=canvas.height;
+
+function clearContext() {
+    ctx.globalCompositeOperation="source-over";
+    ctx.fillStyle = "rgb(0, 255, 0)";
+    ctx.fillRect(0, 0, width, height);
+}
+
+var compositeTypes = [
+    'source-over','source-in','source-out','source-atop',
+    'destination-over','destination-in','destination-out','destination-atop',
+    'lighter','copy','xor'
+];
+
+var expected = [
+    [0, 0, 255], [0, 0, 255], [0, 0, 0], [0, 0, 255],
+    [0, 255, 0], [0, 255, 0], [0, 0, 0], [0, 255, 0],
+    [0, 255, 255], [0, 0, 255], [0, 0, 0]
+];
+
+function testFills(size) {
+    var msg = "size == "+size;
+    debug(msg);
+    for (var i=0; i < compositeTypes.length; i++) {
+        clearContext(ctx);
+        ctx.fillStyle = "rgb(0, 0, 255)";
+        ctx.globalCompositeOperation = compositeTypes[i];
+        debug(compositeTypes[i]);
+        ctx.fillRect(0, 0, size, size);
+        var data = "" 0, width, height);
+        for (var x = 0; x < 3; x++) {
+            var msg = "Actual: " + data.data[x] + " Expected: " + expected[i][x];
+            if (data.data[x] == expected[i][x])
+                testPassed(msg);
+            else
+                testFailed(msg);
+        }
+    }
+}
+
+testFills(10000);
+testFills(50000);
+testFills(100000);
+
+</script>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (95079 => 95080)


--- trunk/Source/WebCore/ChangeLog	2011-09-14 07:40:25 UTC (rev 95079)
+++ trunk/Source/WebCore/ChangeLog	2011-09-14 08:10:05 UTC (rev 95080)
@@ -1,3 +1,22 @@
+2011-09-14  Ben Wells  <benwe...@chromium.org>
+
+        Large canvas fills should not crash or create unnecessarily large image buffers
+        https://bugs.webkit.org/show_bug.cgi?id=67988
+
+        When using source-in, destination-in, source-out, or destination-atop a temporary
+        buffer is created. This buffer only needs to be big enough to cover the intersection
+        of the path and the canvas.
+
+        This change also adds some null checks for failures to create contexts or buffers.
+
+        Reviewed by Stephen White.
+
+        Test: fast/canvas/canvas-large-fills.html
+
+        * html/canvas/CanvasRenderingContext2D.cpp:
+        (WebCore::CanvasRenderingContext2D::clearCanvas):
+        (WebCore::CanvasRenderingContext2D::fillAndDisplayTransparencyElsewhere):
+
 2011-09-14  Kentaro Hara  <hara...@google.com>
 
         Implement a PageTransitionEvent constructor for JSC

Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp (95079 => 95080)


--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp	2011-09-14 07:40:25 UTC (rev 95079)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp	2011-09-14 08:10:05 UTC (rev 95080)
@@ -1472,6 +1472,8 @@
 {
     FloatRect canvasRect(0, 0, canvas()->width(), canvas()->height());
     GraphicsContext* c = drawingContext();
+    if (!c)
+        return;
 
     c->save();
     c->setCTM(canvas()->baseTransform());
@@ -1507,20 +1509,26 @@
 {
     ASSERT(shouldDisplayTransparencyElsewhere());
 
+    IntRect canvasRect(0, 0, canvas()->width(), canvas()->height());
+    canvasRect = canvas()->baseTransform().mapRect(canvasRect);
     Path path = transformAreaToDevice(area);
     IntRect bufferRect = enclosingIntRect(path.boundingRect());
+    bufferRect.intersect(canvasRect);
     path.translate(FloatSize(-bufferRect.x(), -bufferRect.y()));
 
     RenderingMode renderMode = canvas()->buffer()->isAccelerated() ? Accelerated : Unaccelerated;
     OwnPtr<ImageBuffer> buffer = ImageBuffer::create(bufferRect.size(), ColorSpaceDeviceRGB, renderMode);
+    if (!buffer)
+        return;
+
     buffer->context()->setCompositeOperation(CompositeSourceOver);
     state().m_fillStyle->applyFillColor(buffer->context());
     buffer->context()->fillPath(path);
 
-    FloatRect canvasRect(0, 0, canvas()->width(), canvas()->height());
-    canvasRect = canvas()->baseTransform().mapRect(canvasRect);
+    GraphicsContext* c = drawingContext();
+    if (!c)
+        return;
 
-    GraphicsContext* c = drawingContext();
     c->save();
     c->setCTM(AffineTransform());
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to