Title: [148859] trunk
Revision
148859
Author
[email protected]
Date
2013-04-21 23:54:32 -0700 (Sun, 21 Apr 2013)

Log Message

Division by zero in CSSGradientValue::addStops()
https://bugs.webkit.org/show_bug.cgi?id=114807

Patch by Carlos Garcia Campos <[email protected]> on 2013-04-21
Reviewed by Dean Jackson.

Source/WebCore:

The normalization of the color stop positions of a linear gradient
doesn't take into account that the first and last position can be
the same. In such case the positions are computed dividing by 0.
Clamp the positions to 1 without moving the end points in such
case to match what other browsers do. This ensures that positions
passed to the platform gradient are in the 0-1 range which fixes a
crash due to an assert in BlackBerry port running test
fast/forms/type-after-focus-rule-shrink-width.html.

Test: fast/gradients/css3-color-stop-invalid.html

* css/CSSGradientValue.cpp:
(WebCore::CSSGradientValue::addStops):

LayoutTests:

* fast/gradients/css3-color-stop-invalid-expected.html: Added.
* fast/gradients/css3-color-stop-invalid.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (148858 => 148859)


--- trunk/LayoutTests/ChangeLog	2013-04-22 06:52:25 UTC (rev 148858)
+++ trunk/LayoutTests/ChangeLog	2013-04-22 06:54:32 UTC (rev 148859)
@@ -1,3 +1,13 @@
+2013-04-21  Carlos Garcia Campos  <[email protected]>
+
+        Division by zero in CSSGradientValue::addStops()
+        https://bugs.webkit.org/show_bug.cgi?id=114807
+
+        Reviewed by Dean Jackson.
+
+        * fast/gradients/css3-color-stop-invalid-expected.html: Added.
+        * fast/gradients/css3-color-stop-invalid.html: Added.
+
 2013-04-21  Commit Queue  <[email protected]>
 
         Unreviewed, rolling out r148851.

Added: trunk/LayoutTests/fast/gradients/css3-color-stop-invalid-expected.html (0 => 148859)


--- trunk/LayoutTests/fast/gradients/css3-color-stop-invalid-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/gradients/css3-color-stop-invalid-expected.html	2013-04-22 06:54:32 UTC (rev 148859)
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<style>
+.box {
+    display: inline-block;
+    height: 100px;
+    width: 300px;
+    margin: 10px;
+    border: 1px solid black;
+    background-repeat: no-repeat;
+}
+</style>
+<h2>This should be an empty box</h2>
+<div class="box"></div>
+

Added: trunk/LayoutTests/fast/gradients/css3-color-stop-invalid.html (0 => 148859)


--- trunk/LayoutTests/fast/gradients/css3-color-stop-invalid.html	                        (rev 0)
+++ trunk/LayoutTests/fast/gradients/css3-color-stop-invalid.html	2013-04-22 06:54:32 UTC (rev 148859)
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<style>
+.box {
+    display: inline-block;
+    height: 100px;
+    width: 300px;
+    margin: 10px;
+    border: 1px solid black;
+    background-repeat: no-repeat;
+}
+
+.linear {
+    background-image: -webkit-linear-gradient(left, white 310px, green 300px);
+    background-image: -moz-linear-gradient(left, white 310px, green 300px);
+}
+</style>
+<h2>This should be an empty box</h2>
+<div class="linear box"></div>
+

Modified: trunk/Source/WebCore/ChangeLog (148858 => 148859)


--- trunk/Source/WebCore/ChangeLog	2013-04-22 06:52:25 UTC (rev 148858)
+++ trunk/Source/WebCore/ChangeLog	2013-04-22 06:54:32 UTC (rev 148859)
@@ -1,3 +1,24 @@
+2013-04-21  Carlos Garcia Campos  <[email protected]>
+
+        Division by zero in CSSGradientValue::addStops()
+        https://bugs.webkit.org/show_bug.cgi?id=114807
+
+        Reviewed by Dean Jackson.
+
+        The normalization of the color stop positions of a linear gradient
+        doesn't take into account that the first and last position can be
+        the same. In such case the positions are computed dividing by 0.
+        Clamp the positions to 1 without moving the end points in such
+        case to match what other browsers do. This ensures that positions
+        passed to the platform gradient are in the 0-1 range which fixes a
+        crash due to an assert in BlackBerry port running test
+        fast/forms/type-after-focus-rule-shrink-width.html.
+
+        Test: fast/gradients/css3-color-stop-invalid.html
+
+        * css/CSSGradientValue.cpp:
+        (WebCore::CSSGradientValue::addStops):
+
 2013-04-21  Benjamin Poulain  <[email protected]>
 
         Fix some minor bad use of strings in WebCore

Modified: trunk/Source/WebCore/css/CSSGradientValue.cpp (148858 => 148859)


--- trunk/Source/WebCore/css/CSSGradientValue.cpp	2013-04-22 06:52:25 UTC (rev 148858)
+++ trunk/Source/WebCore/css/CSSGradientValue.cpp	2013-04-22 06:54:32 UTC (rev 148859)
@@ -340,15 +340,21 @@
         if (isLinearGradient()) {
             float firstOffset = stops[0].offset;
             float lastOffset = stops[numStops - 1].offset;
-            float scale = lastOffset - firstOffset;
+            if (firstOffset != lastOffset) {
+                float scale = lastOffset - firstOffset;
 
-            for (size_t i = 0; i < numStops; ++i)
-                stops[i].offset = (stops[i].offset - firstOffset) / scale;
+                for (size_t i = 0; i < numStops; ++i)
+                    stops[i].offset = (stops[i].offset - firstOffset) / scale;
 
-            FloatPoint p0 = gradient->p0();
-            FloatPoint p1 = gradient->p1();
-            gradient->setP0(FloatPoint(p0.x() + firstOffset * (p1.x() - p0.x()), p0.y() + firstOffset * (p1.y() - p0.y())));
-            gradient->setP1(FloatPoint(p1.x() + (lastOffset - 1) * (p1.x() - p0.x()), p1.y() + (lastOffset - 1) * (p1.y() - p0.y())));
+                FloatPoint p0 = gradient->p0();
+                FloatPoint p1 = gradient->p1();
+                gradient->setP0(FloatPoint(p0.x() + firstOffset * (p1.x() - p0.x()), p0.y() + firstOffset * (p1.y() - p0.y())));
+                gradient->setP1(FloatPoint(p1.x() + (lastOffset - 1) * (p1.x() - p0.x()), p1.y() + (lastOffset - 1) * (p1.y() - p0.y())));
+            } else {
+                // There's a single position that is outside the scale, clamp the positions to 1.
+                for (size_t i = 0; i < numStops; ++i)
+                    stops[i].offset = 1;
+            }
         } else if (isRadialGradient()) {
             // Rather than scaling the points < 0, we truncate them, so only scale according to the largest point.
             float firstOffset = 0;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to