Title: [116458] trunk
Revision
116458
Author
[email protected]
Date
2012-05-08 15:29:07 -0700 (Tue, 08 May 2012)

Log Message

Prevent crash in animated lists
https://bugs.webkit.org/show_bug.cgi?id=85382

Reviewed by Nikolas Zimmermann.

Source/WebCore:

Animated lists blindly assign the last list value to m_toAtEndOfDurationType
in SVGAnimationElement::startedActiveInterval. If the last list value's length
is larger or smaller than the animated "to" length, we crash.

This change prevents accessing values off the end of toAtEndOfDuration by adding
a check for this case. It may seem inefficient to perform this check on every
animation update but the "to" value can change (in cardinality) while animating.

I checked each of the other animation types (e.g., SVGAnimatedAngle,
SVGAnimatedBoolean, etc.) and was only able to hit this style of crash
in the three types modified in this change:
SVGAnimatedLengthList, SVGAnimatedNumberList, and SVGAnimatedPointList.

Tests: svg/animations/animate-linear-discrete-additive-b-expected.svg
       svg/animations/animate-linear-discrete-additive-b.svg
       svg/animations/animate-linear-discrete-additive-c-expected.svg
       svg/animations/animate-linear-discrete-additive-c.svg
       svg/animations/animate-linear-discrete-additive-expected.svg
       svg/animations/animate-linear-discrete-additive.svg
       svg/animations/animate-list-crash.svg

* svg/SVGAnimatedLengthList.cpp:
(WebCore::SVGAnimatedLengthListAnimator::calculateAnimatedValue):
* svg/SVGAnimatedNumberList.cpp:
(WebCore::SVGAnimatedNumberListAnimator::calculateAnimatedValue):
* svg/SVGAnimatedPointList.cpp:
(WebCore::SVGAnimatedPointListAnimator::calculateAnimatedValue):

LayoutTests:

* svg/animations/animate-linear-discrete-additive-b-expected.svg: Added.
* svg/animations/animate-linear-discrete-additive-b.svg: Added.
* svg/animations/animate-linear-discrete-additive-c-expected.svg: Added.
* svg/animations/animate-linear-discrete-additive-c.svg: Added.
* svg/animations/animate-linear-discrete-additive-expected.svg: Added.
* svg/animations/animate-linear-discrete-additive.svg: Added.
* svg/animations/animate-list-crash-expected.txt: Added.
* svg/animations/animate-list-crash.svg: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (116457 => 116458)


--- trunk/LayoutTests/ChangeLog	2012-05-08 22:04:23 UTC (rev 116457)
+++ trunk/LayoutTests/ChangeLog	2012-05-08 22:29:07 UTC (rev 116458)
@@ -1,3 +1,19 @@
+2012-05-08  Philip Rogers  <[email protected]>
+
+        Prevent crash in animated lists
+        https://bugs.webkit.org/show_bug.cgi?id=85382
+
+        Reviewed by Nikolas Zimmermann.
+
+        * svg/animations/animate-linear-discrete-additive-b-expected.svg: Added.
+        * svg/animations/animate-linear-discrete-additive-b.svg: Added.
+        * svg/animations/animate-linear-discrete-additive-c-expected.svg: Added.
+        * svg/animations/animate-linear-discrete-additive-c.svg: Added.
+        * svg/animations/animate-linear-discrete-additive-expected.svg: Added.
+        * svg/animations/animate-linear-discrete-additive.svg: Added.
+        * svg/animations/animate-list-crash-expected.txt: Added.
+        * svg/animations/animate-list-crash.svg: Added.
+
 2012-05-08  Ojan Vafai  <[email protected]>
 
         Chromium rebaselines after http://trac.webkit.org/changeset/116438.

Added: trunk/LayoutTests/svg/animations/animate-linear-discrete-additive-b-expected.svg (0 => 116458)


--- trunk/LayoutTests/svg/animations/animate-linear-discrete-additive-b-expected.svg	                        (rev 0)
+++ trunk/LayoutTests/svg/animations/animate-linear-discrete-additive-b-expected.svg	2012-05-08 22:29:07 UTC (rev 116458)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg viewBox="0 0 300 200" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(50,20)">
+    <text x="2,3,4,5" y="0">
+        ABC
+    </text>
+    <text x="1" y="30">
+        DEF
+    </text>
+    <text x="120" y="60">
+        GHI
+    </text>
+    <text x="160 0" y="90">
+        JKL
+    </text>
+</g>
+</svg>

Added: trunk/LayoutTests/svg/animations/animate-linear-discrete-additive-b.svg (0 => 116458)


--- trunk/LayoutTests/svg/animations/animate-linear-discrete-additive-b.svg	                        (rev 0)
+++ trunk/LayoutTests/svg/animations/animate-linear-discrete-additive-b.svg	2012-05-08 22:29:07 UTC (rev 116458)
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg viewBox="0 0 300 200" xmlns="http://www.w3.org/2000/svg" _onload_="loaded()">
+<title>Test mixed cardinality animations</title>
+<g transform="translate(50,20)">
+    <text x="0" y="0">
+        <!-- Test that an animated list of different cardinality works properly -->
+        ABC
+        <animate attributeName="x" dur="5s" repeatCount="10" values="1; 2,3,4,5; 3"/>
+    </text>
+    <text x="0" y="30">
+        <!-- Test that an animated list of different cardinality works properly -->
+        DEF
+        <animate attributeName="x" dur="7s" repeatCount="10" values="1; 2,3,4,5; 3"/>
+    </text>
+    <text y="60">
+        <!-- Test that an sum works properly with mixed cardinality -->
+        GHI
+        <animate attributeName="x" additive="sum" accumulate="sum" dur="2s" repeatCount="25" values="0; 10; 20 20; 30" calcMode="linear" />
+    </text>
+    <text y="90">
+        <!-- Test that an sum works properly with mixed cardinality -->
+        JKL
+        <animate attributeName="x" additive="sum" accumulate="sum" dur="2s" repeatCount="25" values="0 0; 10 10; 40" calcMode="linear" />
+    </text>
+</g>
+<script>
+if (window.layoutTestController)
+    layoutTestController.waitUntilDone();
+
+function loaded() {
+    document.documentElement.setCurrentTime(8);
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+</script>
+</svg>

Added: trunk/LayoutTests/svg/animations/animate-linear-discrete-additive-c-expected.svg (0 => 116458)


--- trunk/LayoutTests/svg/animations/animate-linear-discrete-additive-c-expected.svg	                        (rev 0)
+++ trunk/LayoutTests/svg/animations/animate-linear-discrete-additive-c-expected.svg	2012-05-08 22:29:07 UTC (rev 116458)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg viewBox="0 0 300 200" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(50,20)">
+    <text x="1" y="0">
+        ABC
+    </text>
+    <text x="2,3,4,5" y="30">
+        DEF
+    </text>
+    <text x="10" y="60">
+        GHI
+    </text>
+    <text x="10 10" y="90">
+        JKL
+    </text>
+</g>
+</svg>

Added: trunk/LayoutTests/svg/animations/animate-linear-discrete-additive-c.svg (0 => 116458)


--- trunk/LayoutTests/svg/animations/animate-linear-discrete-additive-c.svg	                        (rev 0)
+++ trunk/LayoutTests/svg/animations/animate-linear-discrete-additive-c.svg	2012-05-08 22:29:07 UTC (rev 116458)
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg viewBox="0 0 300 200" xmlns="http://www.w3.org/2000/svg" _onload_="loaded()">
+<title>Test mixed cardinality animations</title>
+<g transform="translate(50,20)">
+    <text x="0" y="0">
+        <!-- Test that an animated list of different cardinality works properly -->
+        ABC
+        <animate attributeName="x" dur="5s" repeatCount="10" values="1; 2,3,4,5; 3"/>
+    </text>
+    <text x="0" y="30">
+        <!-- Test that an animated list of different cardinality works properly -->
+        DEF
+        <animate attributeName="x" dur="7s" repeatCount="10" values="1; 2,3,4,5; 3"/>
+    </text>
+    <text y="60">
+        <!-- Test that an sum works properly with mixed cardinality -->
+        GHI
+        <animate attributeName="x" additive="sum" accumulate="sum" dur="2s" repeatCount="25" values="0; 10; 20 20; 30" calcMode="linear" />
+    </text>
+    <text y="90">
+        <!-- Test that an sum works properly with mixed cardinality -->
+        JKL
+        <animate attributeName="x" additive="sum" accumulate="sum" dur="2s" repeatCount="25" values="0 0; 10 10; 40" calcMode="linear" />
+    </text>
+</g>
+<script>
+if (window.layoutTestController)
+    layoutTestController.waitUntilDone();
+
+function loaded() {
+    document.documentElement.setCurrentTime(11);
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+</script>
+</svg>

Added: trunk/LayoutTests/svg/animations/animate-linear-discrete-additive-expected.svg (0 => 116458)


--- trunk/LayoutTests/svg/animations/animate-linear-discrete-additive-expected.svg	                        (rev 0)
+++ trunk/LayoutTests/svg/animations/animate-linear-discrete-additive-expected.svg	2012-05-08 22:29:07 UTC (rev 116458)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg viewBox="0 0 300 200" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(50,20)">
+    <text x="2,3,4" y="0">
+        ABC
+    </text>
+    <text x="1" y="30">
+        DEF
+    </text>
+    <text x="90" y="60">
+        GHI
+    </text>
+    <text x="120 0" y="90">
+        JKL
+    </text>
+</g>
+</svg>

Added: trunk/LayoutTests/svg/animations/animate-linear-discrete-additive.svg (0 => 116458)


--- trunk/LayoutTests/svg/animations/animate-linear-discrete-additive.svg	                        (rev 0)
+++ trunk/LayoutTests/svg/animations/animate-linear-discrete-additive.svg	2012-05-08 22:29:07 UTC (rev 116458)
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg viewBox="0 0 300 200" xmlns="http://www.w3.org/2000/svg" _onload_="loaded()">
+<title>Test mixed cardinality animations</title>
+<g transform="translate(50,20)">
+    <text x="0" y="0">
+        <!-- Test that an animated list of different cardinality works properly -->
+        ABC
+        <animate attributeName="x" dur="5s" repeatCount="10" values="1; 2,3,4,5; 3"/>
+    </text>
+    <text x="0" y="30">
+        <!-- Test that an animated list of different cardinality works properly -->
+        DEF
+        <animate attributeName="x" dur="20s" repeatCount="10" values="1; 2,3,4,5; 3"/>
+    </text>
+    <text y="60">
+        <!-- Test that an sum works properly with mixed cardinality -->
+        GHI
+        <animate attributeName="x" additive="sum" accumulate="sum" dur="1s" repeatCount="10" values="0; 10; 20 20; 30" calcMode="linear" />
+    </text>
+    <text y="90">
+        <!-- Test that an sum works properly with mixed cardinality -->
+        JKL
+        <animate attributeName="x" additive="sum" accumulate="sum" dur="1s" repeatCount="10" values="0 0; 10 10; 40" calcMode="linear" />
+    </text>
+</g>
+<script>
+if (window.layoutTestController)
+    layoutTestController.waitUntilDone();
+
+function loaded() {
+    document.documentElement.setCurrentTime(3);
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+</script>
+</svg>

Added: trunk/LayoutTests/svg/animations/animate-list-crash-expected.txt (0 => 116458)


--- trunk/LayoutTests/svg/animations/animate-list-crash-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/svg/animations/animate-list-crash-expected.txt	2012-05-08 22:29:07 UTC (rev 116458)
@@ -0,0 +1 @@
+PASS

Added: trunk/LayoutTests/svg/animations/animate-list-crash.svg (0 => 116458)


--- trunk/LayoutTests/svg/animations/animate-list-crash.svg	                        (rev 0)
+++ trunk/LayoutTests/svg/animations/animate-list-crash.svg	2012-05-08 22:29:07 UTC (rev 116458)
@@ -0,0 +1,24 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+  <!-- Test for WK85382 - passes if there is no crash -->
+  <polygon>
+    <animate values="1,2; 3,4; abc" attributeName="points"/>
+  </polygon>
+  <tspan>
+     <animate values="1; 2; a" attributeName="rotate"/>
+  </tspan>
+  <tspan>
+     <animate values="1; 2; a" attributeName="x"/>
+  </tspan>
+  <path>
+     <!-- doesn't crash but added to catch regressions -->
+     <animate values="m1,1 2,2z; m1,1 2,2z; m1,1z" attributeName="d"/>
+  </path>
+  <text id="log"/>
+  <script>
+  <![CDATA[
+    document.getElementById("log").appendChild(document.createTextNode("PASS"));
+    if (window.layoutTestController)
+      window.layoutTestController.dumpAsText();
+  ]]>
+  </script>
+</svg>

Modified: trunk/Source/WebCore/ChangeLog (116457 => 116458)


--- trunk/Source/WebCore/ChangeLog	2012-05-08 22:04:23 UTC (rev 116457)
+++ trunk/Source/WebCore/ChangeLog	2012-05-08 22:29:07 UTC (rev 116458)
@@ -1,3 +1,38 @@
+2012-05-08  Philip Rogers  <[email protected]>
+
+        Prevent crash in animated lists
+        https://bugs.webkit.org/show_bug.cgi?id=85382
+
+        Reviewed by Nikolas Zimmermann.
+
+        Animated lists blindly assign the last list value to m_toAtEndOfDurationType
+        in SVGAnimationElement::startedActiveInterval. If the last list value's length
+        is larger or smaller than the animated "to" length, we crash.
+
+        This change prevents accessing values off the end of toAtEndOfDuration by adding
+        a check for this case. It may seem inefficient to perform this check on every
+        animation update but the "to" value can change (in cardinality) while animating.
+
+        I checked each of the other animation types (e.g., SVGAnimatedAngle,
+        SVGAnimatedBoolean, etc.) and was only able to hit this style of crash
+        in the three types modified in this change:
+        SVGAnimatedLengthList, SVGAnimatedNumberList, and SVGAnimatedPointList.
+
+        Tests: svg/animations/animate-linear-discrete-additive-b-expected.svg
+               svg/animations/animate-linear-discrete-additive-b.svg
+               svg/animations/animate-linear-discrete-additive-c-expected.svg
+               svg/animations/animate-linear-discrete-additive-c.svg
+               svg/animations/animate-linear-discrete-additive-expected.svg
+               svg/animations/animate-linear-discrete-additive.svg
+               svg/animations/animate-list-crash.svg
+
+        * svg/SVGAnimatedLengthList.cpp:
+        (WebCore::SVGAnimatedLengthListAnimator::calculateAnimatedValue):
+        * svg/SVGAnimatedNumberList.cpp:
+        (WebCore::SVGAnimatedNumberListAnimator::calculateAnimatedValue):
+        * svg/SVGAnimatedPointList.cpp:
+        (WebCore::SVGAnimatedPointListAnimator::calculateAnimatedValue):
+
 2012-05-08  Rafael Weinstein  <[email protected]>
 
         HTMLElementStack::hasOnlyHTMLElementsInScope is no longer called

Modified: trunk/Source/WebCore/svg/SVGAnimatedLengthList.cpp (116457 => 116458)


--- trunk/Source/WebCore/svg/SVGAnimatedLengthList.cpp	2012-05-08 22:04:23 UTC (rev 116457)
+++ trunk/Source/WebCore/svg/SVGAnimatedLengthList.cpp	2012-05-08 22:29:07 UTC (rev 116458)
@@ -111,6 +111,7 @@
 
     unsigned fromLengthListSize = fromLengthList.size();
     unsigned toLengthListSize = toLengthList.size();
+    unsigned toAtEndOfDurationListSize = toAtEndOfDurationLengthList.size();
 
     SVGLengthContext lengthContext(m_contextElement);
     ExceptionCode ec = 0;
@@ -123,8 +124,9 @@
                 unitType = fromLengthList[i].unitType();
             effectiveFrom = fromLengthList[i].value(lengthContext);
         }
+        float effectiveToAtEnd = i < toAtEndOfDurationListSize ? toAtEndOfDurationLengthList[i].value(lengthContext) : 0;
 
-        m_animationElement->animateAdditiveNumber(percentage, repeatCount, effectiveFrom, toLengthList[i].value(lengthContext), toAtEndOfDurationLengthList[i].value(lengthContext), animatedNumber);
+        m_animationElement->animateAdditiveNumber(percentage, repeatCount, effectiveFrom, toLengthList[i].value(lengthContext), effectiveToAtEnd, animatedNumber);
         animatedLengthList[i].setValue(lengthContext, animatedNumber, m_lengthMode, unitType, ec);
         ASSERT(!ec);
     }

Modified: trunk/Source/WebCore/svg/SVGAnimatedNumberList.cpp (116457 => 116458)


--- trunk/Source/WebCore/svg/SVGAnimatedNumberList.cpp	2012-05-08 22:04:23 UTC (rev 116457)
+++ trunk/Source/WebCore/svg/SVGAnimatedNumberList.cpp	2012-05-08 22:29:07 UTC (rev 116458)
@@ -93,10 +93,12 @@
 
     unsigned fromNumberListSize = fromNumberList.size();
     unsigned toNumberListSize = toNumberList.size();
+    unsigned toAtEndOfDurationSize = toAtEndOfDurationNumberList.size();
 
     for (unsigned i = 0; i < toNumberListSize; ++i) {
         float effectiveFrom = fromNumberListSize ? fromNumberList[i] : 0;
-        m_animationElement->animateAdditiveNumber(percentage, repeatCount, effectiveFrom, toNumberList[i], toAtEndOfDurationNumberList[i], animatedNumberList[i]);
+        float effectiveToAtEnd = i < toAtEndOfDurationSize ? toAtEndOfDurationNumberList[i] : 0;
+        m_animationElement->animateAdditiveNumber(percentage, repeatCount, effectiveFrom, toNumberList[i], effectiveToAtEnd, animatedNumberList[i]);
     }
 }
 

Modified: trunk/Source/WebCore/svg/SVGAnimatedPointList.cpp (116457 => 116458)


--- trunk/Source/WebCore/svg/SVGAnimatedPointList.cpp	2012-05-08 22:04:23 UTC (rev 116457)
+++ trunk/Source/WebCore/svg/SVGAnimatedPointList.cpp	2012-05-08 22:29:07 UTC (rev 116458)
@@ -94,16 +94,18 @@
 
     unsigned fromPointListSize = fromPointList.size();
     unsigned toPointListSize = toPointList.size();
+    unsigned toAtEndOfDurationSize = toAtEndOfDurationPointList.size();
 
     for (unsigned i = 0; i < toPointListSize; ++i) {
         FloatPoint effectiveFrom;
         if (fromPointListSize)
             effectiveFrom = fromPointList[i];
+        FloatPoint effectiveToAtEnd = i < toAtEndOfDurationSize ? toAtEndOfDurationPointList[i] : FloatPoint();
 
         float animatedX = animatedPointList[i].x();
         float animatedY = animatedPointList[i].y();
-        m_animationElement->animateAdditiveNumber(percentage, repeatCount, effectiveFrom.x(), toPointList[i].x(), toAtEndOfDurationPointList[i].x(), animatedX);
-        m_animationElement->animateAdditiveNumber(percentage, repeatCount, effectiveFrom.y(), toPointList[i].y(), toAtEndOfDurationPointList[i].y(), animatedY);
+        m_animationElement->animateAdditiveNumber(percentage, repeatCount, effectiveFrom.x(), toPointList[i].x(), effectiveToAtEnd.x(), animatedX);
+        m_animationElement->animateAdditiveNumber(percentage, repeatCount, effectiveFrom.y(), toPointList[i].y(), effectiveToAtEnd.y(), animatedY);
         animatedPointList[i] = FloatPoint(animatedX, animatedY);
     }
 }
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to