[CSS Shapes] Properly handle negative reference box widths and center coordinates
authorbjonesbe@adobe.com <bjonesbe@adobe.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Apr 2015 19:40:43 +0000 (19:40 +0000)
committerbjonesbe@adobe.com <bjonesbe@adobe.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Apr 2015 19:40:43 +0000 (19:40 +0000)
https://bugs.webkit.org/show_bug.cgi?id=142610

Reviewed by Rob Buis.
Source/WebCore:

Fix a few cases where values that should not be negative end up that
way.

This patch is based on a couple of Blink patches by Rob Buis.

Tests: fast/shapes/shape-outside-floats/shape-outside-floats-circle-negative-radius-crash.html
       fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-negative-width-crash.html

* rendering/shapes/ShapeOutsideInfo.cpp:
(WebCore::ShapeOutsideInfo::computeDeltasForContainingBlockLine): A
    negative margin box width means that the shape has no extent, so
    clamp to zero.
* rendering/style/BasicShapes.cpp:
(WebCore::BasicShapeCircle::floatValueForRadiusInBox): When computing
    the radii, take the absolute value, since the radii is based on
    the distance, which is always positive.
(WebCore::BasicShapeEllipse::floatValueForRadiusInBox): Ditto.

LayoutTests:

Tests for the cases that trigger asserts.

* fast/shapes/shape-outside-floats/shape-outside-floats-circle-negative-radius-crash-expected.txt: Added.
* fast/shapes/shape-outside-floats/shape-outside-floats-circle-negative-radius-crash.html: Added.
* fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-negative-width-crash-expected.txt: Added.
* fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-negative-width-crash.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@182560 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-circle-negative-radius-crash-expected.txt [new file with mode: 0644]
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-circle-negative-radius-crash.html [new file with mode: 0644]
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-negative-width-crash-expected.txt [new file with mode: 0644]
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-negative-width-crash.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/shapes/ShapeOutsideInfo.cpp
Source/WebCore/rendering/style/BasicShapes.cpp

index 455d303..9ad8999 100644 (file)
@@ -1,3 +1,17 @@
+2015-04-08  Bem Jones-Bey  <bjonesbe@adobe.com>
+
+        [CSS Shapes] Properly handle negative reference box widths and center coordinates
+        https://bugs.webkit.org/show_bug.cgi?id=142610
+
+        Reviewed by Rob Buis.
+        
+        Tests for the cases that trigger asserts.
+
+        * fast/shapes/shape-outside-floats/shape-outside-floats-circle-negative-radius-crash-expected.txt: Added.
+        * fast/shapes/shape-outside-floats/shape-outside-floats-circle-negative-radius-crash.html: Added.
+        * fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-negative-width-crash-expected.txt: Added.
+        * fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-negative-width-crash.html: Added.
+
 2015-04-08  ChangSeok Oh  <changseok.oh@collabora.com>
 
         Fill list style background with same color with that of list background.
diff --git a/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-circle-negative-radius-crash-expected.txt b/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-circle-negative-radius-crash-expected.txt
new file mode 100644 (file)
index 0000000..22fb7e5
--- /dev/null
@@ -0,0 +1 @@
+a This test passes if it doesn't crash.
diff --git a/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-circle-negative-radius-crash.html b/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-circle-negative-radius-crash.html
new file mode 100644 (file)
index 0000000..8611e06
--- /dev/null
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<style>
+div {
+    -webkit-shape-outside: padding-box circle(closest-side at 75px 80px);
+    float: right;
+}
+</style>
+<div>a</div>
+This test passes if it doesn't crash.
+<script>
+    if (window.testRunner) {
+        testRunner.dumpAsText();
+    }
+</script>
diff --git a/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-negative-width-crash-expected.txt b/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-negative-width-crash-expected.txt
new file mode 100644 (file)
index 0000000..22fb7e5
--- /dev/null
@@ -0,0 +1 @@
+a This test passes if it doesn't crash.
diff --git a/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-negative-width-crash.html b/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-negative-width-crash.html
new file mode 100644 (file)
index 0000000..e118334
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<style>
+div {
+    float: right;
+    -webkit-shape-outside: ellipse(2257% 6317vmax);
+    margin-right:-3553%;
+}
+</style>
+<div>a</div>
+This test passes if it doesn't crash.
+<script>
+    if (window.testRunner) {
+        testRunner.dumpAsText();
+    }
+</script>
index b91f6a6..48d4653 100644 (file)
@@ -1,3 +1,28 @@
+2015-04-08  Bem Jones-Bey  <bjonesbe@adobe.com>
+
+        [CSS Shapes] Properly handle negative reference box widths and center coordinates
+        https://bugs.webkit.org/show_bug.cgi?id=142610
+
+        Reviewed by Rob Buis.
+
+        Fix a few cases where values that should not be negative end up that
+        way.
+
+        This patch is based on a couple of Blink patches by Rob Buis.
+
+        Tests: fast/shapes/shape-outside-floats/shape-outside-floats-circle-negative-radius-crash.html
+               fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-negative-width-crash.html
+
+        * rendering/shapes/ShapeOutsideInfo.cpp:
+        (WebCore::ShapeOutsideInfo::computeDeltasForContainingBlockLine): A
+            negative margin box width means that the shape has no extent, so
+            clamp to zero.
+        * rendering/style/BasicShapes.cpp:
+        (WebCore::BasicShapeCircle::floatValueForRadiusInBox): When computing
+            the radii, take the absolute value, since the radii is based on
+            the distance, which is always positive.
+        (WebCore::BasicShapeEllipse::floatValueForRadiusInBox): Ditto.
+
 2015-04-08  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r182522.
index 33011bf..96ad5d0 100644 (file)
@@ -313,7 +313,7 @@ ShapeOutsideDeltas ShapeOutsideInfo::computeDeltasForContainingBlockLine(const R
 
     if (isShapeDirty() || !m_shapeOutsideDeltas.isForLine(borderBoxLineTop, lineHeight)) {
         LayoutUnit referenceBoxLineTop = borderBoxLineTop - logicalTopOffset();
-        LayoutUnit floatMarginBoxWidth = containingBlock.logicalWidthForFloat(&floatingObject);
+        LayoutUnit floatMarginBoxWidth = std::max<LayoutUnit>(LayoutUnit(), containingBlock.logicalWidthForFloat(&floatingObject));
 
         if (computedShape().lineOverlapsShapeMarginBounds(referenceBoxLineTop, lineHeight)) {
             LineSegment segment = computedShape().getExcludedInterval((borderBoxLineTop - logicalTopOffset()), std::min(lineHeight, shapeLogicalBottom() - borderBoxLineTop));
index 3bd8668..873a406 100644 (file)
@@ -96,11 +96,13 @@ float BasicShapeCircle::floatValueForRadiusInBox(float boxWidth, float boxHeight
     float centerX = floatValueForCenterCoordinate(m_centerX, boxWidth);
     float centerY = floatValueForCenterCoordinate(m_centerY, boxHeight);
 
+    float widthDelta = std::abs(boxWidth - centerX);
+    float heightDelta = std::abs(boxHeight - centerY);
     if (m_radius.type() == BasicShapeRadius::ClosestSide)
-        return std::min(std::min(centerX, boxWidth - centerX), std::min(centerY, boxHeight - centerY));
+        return std::min(std::min(std::abs(centerX), widthDelta), std::min(std::abs(centerY), heightDelta));
 
     // If radius.type() == BasicShapeRadius::FarthestSide.
-    return std::max(std::max(centerX, boxWidth - centerX), std::max(centerY, boxHeight - centerY));
+    return std::max(std::max(std::abs(centerX), widthDelta), std::max(std::abs(centerY), heightDelta));
 }
 
 void BasicShapeCircle::path(Path& path, const FloatRect& boundingBox)
@@ -133,13 +135,14 @@ Ref<BasicShape> BasicShapeCircle::blend(const BasicShape& other, double progress
 float BasicShapeEllipse::floatValueForRadiusInBox(const BasicShapeRadius& radius, float center, float boxWidthOrHeight) const
 {
     if (radius.type() == BasicShapeRadius::Value)
-        return floatValueForLength(radius.value(), boxWidthOrHeight);
+        return floatValueForLength(radius.value(), std::abs(boxWidthOrHeight));
 
+    float widthOrHeightDelta = std::abs(boxWidthOrHeight - center);
     if (radius.type() == BasicShapeRadius::ClosestSide)
-        return std::min(center, boxWidthOrHeight - center);
+        return std::min(std::abs(center), widthOrHeightDelta);
 
     ASSERT(radius.type() == BasicShapeRadius::FarthestSide);
-    return std::max(center, boxWidthOrHeight - center);
+    return std::max(std::abs(center), widthOrHeightDelta);
 }
 
 void BasicShapeEllipse::path(Path& path, const FloatRect& boundingBox)