Title: [86928] trunk
Revision
86928
Author
[email protected]
Date
2011-05-20 01:01:19 -0700 (Fri, 20 May 2011)

Log Message

2011-05-20  Dirk Schulze  <[email protected]>

        Reviewed by Eric Seidel.

        SVG Large curve path segment OOM crash
        https://bugs.webkit.org/show_bug.cgi?id=42079

        Limit the depth of repeatedly splitting a segment on length calculation to 20. The limitation
        is necessary for very big segments that would be splitter into millions of parts otherwise.
        The limitation just cause a less accurate approximation.
        At the moment the limit is fixed to 20. This is comparable with splitting the segment into 
        ~1 million parts as a worst case. We might want to be more flexible later.

        Test: svg/custom/path-getTotalLength-on-big-segment-crash.svg

        * platform/graphics/PathTraversalState.cpp:
        (WebCore::midPoint):
        (WebCore::curveLength):
        (WebCore::PathTraversalState::PathTraversalState):
        (WebCore::PathTraversalState::moveTo):
        (WebCore::PathTraversalState::quadraticBezierTo):
        (WebCore::PathTraversalState::cubicBezierTo):
        * platform/graphics/PathTraversalState.h:
2011-05-20  Dirk Schulze  <[email protected]>

        Reviewed by Eric Seidel.

        SVG Large curve path segment OOM crash
        https://bugs.webkit.org/show_bug.cgi?id=42079

        Added a test to verify, that the browser does not crash on calculating the total length on big segments.
        It makes no sense to add the result of getTotalLength(), since they differ a lot bewteen platforms.
        This is caused by the platform graphic libraries. See comment #9 on the bug.

        * svg/custom/path-getTotalLength-on-big-segment-crash-expected.txt: Added.
        * svg/custom/path-getTotalLength-on-big-segment-crash.svg: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (86927 => 86928)


--- trunk/LayoutTests/ChangeLog	2011-05-20 07:56:57 UTC (rev 86927)
+++ trunk/LayoutTests/ChangeLog	2011-05-20 08:01:19 UTC (rev 86928)
@@ -1,3 +1,17 @@
+2011-05-20  Dirk Schulze  <[email protected]>
+
+        Reviewed by Eric Seidel.
+
+        SVG Large curve path segment OOM crash
+        https://bugs.webkit.org/show_bug.cgi?id=42079
+
+        Added a test to verify, that the browser does not crash on calculating the total length on big segments.
+        It makes no sense to add the result of getTotalLength(), since they differ a lot bewteen platforms.
+        This is caused by the platform graphic libraries. See comment #9 on the bug.
+
+        * svg/custom/path-getTotalLength-on-big-segment-crash-expected.txt: Added.
+        * svg/custom/path-getTotalLength-on-big-segment-crash.svg: Added.
+
 2011-05-19  Fumitoshi Ukai  <[email protected]>
 
         Unreviewed.

Added: trunk/LayoutTests/svg/custom/path-getTotalLength-on-big-segment-crash-expected.txt (0 => 86928)


--- trunk/LayoutTests/svg/custom/path-getTotalLength-on-big-segment-crash-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/svg/custom/path-getTotalLength-on-big-segment-crash-expected.txt	2011-05-20 08:01:19 UTC (rev 86928)
@@ -0,0 +1 @@
+Test passes if it does not crash.

Added: trunk/LayoutTests/svg/custom/path-getTotalLength-on-big-segment-crash.svg (0 => 86928)


--- trunk/LayoutTests/svg/custom/path-getTotalLength-on-big-segment-crash.svg	                        (rev 0)
+++ trunk/LayoutTests/svg/custom/path-getTotalLength-on-big-segment-crash.svg	2011-05-20 08:01:19 UTC (rev 86928)
@@ -0,0 +1,19 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<text x="10" y="30">Test passes if it does not crash.</text>
+<script>
+<![CDATA[
+    var path = document.createElementNS("http://www.w3.org/2000/svg", "path");
+    path.setAttribute("d", "M0,0");
+    var x   = -764285429.594597,  y = -4016805151.510674,
+        x1  = -1.227687,          y1 = -4089196561.699610,
+        x2  = -2172808631,        y2 = .990756267;
+    pathSeg = path.createSVGPathSegCurvetoCubicAbs(x, y, x1 ,y1 ,x2 ,y2);
+    pathSegList = path.pathSegList;
+    pathSegList.appendItem(pathSeg);
+    path.getTotalLength();
+    if (window.layoutTestController)
+        layoutTestController.dumpAsText();
+
+]]>
+</script>
+</svg>

Modified: trunk/Source/WebCore/ChangeLog (86927 => 86928)


--- trunk/Source/WebCore/ChangeLog	2011-05-20 07:56:57 UTC (rev 86927)
+++ trunk/Source/WebCore/ChangeLog	2011-05-20 08:01:19 UTC (rev 86928)
@@ -1,3 +1,27 @@
+2011-05-20  Dirk Schulze  <[email protected]>
+
+        Reviewed by Eric Seidel.
+
+        SVG Large curve path segment OOM crash
+        https://bugs.webkit.org/show_bug.cgi?id=42079
+
+        Limit the depth of repeatedly splitting a segment on length calculation to 20. The limitation
+        is necessary for very big segments that would be splitter into millions of parts otherwise.
+        The limitation just cause a less accurate approximation.
+        At the moment the limit is fixed to 20. This is comparable with splitting the segment into 
+        ~1 million parts as a worst case. We might want to be more flexible later.
+
+        Test: svg/custom/path-getTotalLength-on-big-segment-crash.svg
+
+        * platform/graphics/PathTraversalState.cpp:
+        (WebCore::midPoint):
+        (WebCore::curveLength):
+        (WebCore::PathTraversalState::PathTraversalState):
+        (WebCore::PathTraversalState::moveTo):
+        (WebCore::PathTraversalState::quadraticBezierTo):
+        (WebCore::PathTraversalState::cubicBezierTo):
+        * platform/graphics/PathTraversalState.h:
+
 2011-05-20  Leo Yang  <[email protected]>
 
         Reviewed by Nikolas Zimmermann.

Modified: trunk/Source/WebCore/platform/graphics/PathTraversalState.cpp (86927 => 86928)


--- trunk/Source/WebCore/platform/graphics/PathTraversalState.cpp	2011-05-20 07:56:57 UTC (rev 86927)
+++ trunk/Source/WebCore/platform/graphics/PathTraversalState.cpp	2011-05-20 08:01:19 UTC (rev 86928)
@@ -1,8 +1,6 @@
 /*
- * This file is part of the WebKit open source project.
+ * Copyright (C) 2006, 2007 Eric Seidel <[email protected]>
  *
- * Copyright (C) 2006, 2007 Eric Seidel ([email protected])
- *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
  * License as published by the Free Software Foundation; either
@@ -22,10 +20,9 @@
 #include "config.h"
 #include "PathTraversalState.h"
 
-#include "Path.h"
+#include <wtf/MathExtras.h>
+#include <wtf/Vector.h>
 
-#include <math.h>
-
 namespace WebCore {
 
 static const float kPathSegmentLengthTolerance = 0.00001f;
@@ -119,17 +116,20 @@
 template<class CurveType>
 static float curveLength(PathTraversalState& traversalState, CurveType curve)
 {
+    static const unsigned curveStackDepthLimit = 20;
+
     Vector<CurveType> curveStack;
     curveStack.append(curve);
 
-    float totalLength = 0.0f;
+    float totalLength = 0;
     do {
         float length = curve.approximateDistance();
-        if ((length - distanceLine(curve.start, curve.end)) > kPathSegmentLengthTolerance) {
-            CurveType left, right;
-            curve.split(left, right);
-            curve = left;
-            curveStack.append(right);
+        if ((length - distanceLine(curve.start, curve.end)) > kPathSegmentLengthTolerance && curveStack.size() <= curveStackDepthLimit) {
+            CurveType leftCurve;
+            CurveType rightCurve;
+            curve.split(leftCurve, rightCurve);
+            curve = leftCurve;
+            curveStack.append(rightCurve);
         } else {
             totalLength += length;
             if (traversalState.m_action == PathTraversalState::TraversalPointAtLength
@@ -150,10 +150,10 @@
 PathTraversalState::PathTraversalState(PathTraversalAction action)
     : m_action(action)
     , m_success(false)
-    , m_totalLength(0.0f)
+    , m_totalLength(0)
     , m_segmentIndex(0)
-    , m_desiredLength(0.0f)
-    , m_normalAngle(0.0f)
+    , m_desiredLength(0)
+    , m_normalAngle(0)
 {
 }
 
@@ -167,7 +167,7 @@
 float PathTraversalState::moveTo(const FloatPoint& point)
 {
     m_current = m_start = m_control1 = m_control2 = point;
-    return 0.0f;
+    return 0;
 }
 
 float PathTraversalState::lineTo(const FloatPoint& point)

Modified: trunk/Source/WebCore/platform/graphics/PathTraversalState.h (86927 => 86928)


--- trunk/Source/WebCore/platform/graphics/PathTraversalState.h	2011-05-20 07:56:57 UTC (rev 86927)
+++ trunk/Source/WebCore/platform/graphics/PathTraversalState.h	2011-05-20 08:01:19 UTC (rev 86928)
@@ -27,46 +27,45 @@
 #define PathTraversalState_h
 
 #include "FloatPoint.h"
-#include <wtf/Vector.h>
 
 namespace WebCore {
-    
-    class Path;
-    
-    class PathTraversalState {
-    public:
-        enum PathTraversalAction {
-            TraversalTotalLength,
-            TraversalPointAtLength,
-            TraversalSegmentAtLength,
-            TraversalNormalAngleAtLength
-        };
-        
-        PathTraversalState(PathTraversalAction);
-        
-        float closeSubpath();
-        float moveTo(const FloatPoint&);
-        float lineTo(const FloatPoint&);
-        float quadraticBezierTo(const FloatPoint& newControl, const FloatPoint& newEnd);
-        float cubicBezierTo(const FloatPoint& newControl1, const FloatPoint& newControl2, const FloatPoint& newEnd);
-        
-    public:
-        PathTraversalAction m_action;
-        bool m_success;
-        
-        FloatPoint m_current;
-        FloatPoint m_start;
-        FloatPoint m_control1;
-        FloatPoint m_control2;
-        
-        float m_totalLength;
-        unsigned m_segmentIndex;
-        float m_desiredLength;
-        
-        // For normal calculations
-        FloatPoint m_previous;
-        float m_normalAngle; // degrees
-    };    
+
+class Path;
+
+class PathTraversalState {
+public:
+    enum PathTraversalAction {
+        TraversalTotalLength,
+        TraversalPointAtLength,
+        TraversalSegmentAtLength,
+        TraversalNormalAngleAtLength
+    };
+
+    PathTraversalState(PathTraversalAction);
+
+    float closeSubpath();
+    float moveTo(const FloatPoint&);
+    float lineTo(const FloatPoint&);
+    float quadraticBezierTo(const FloatPoint& newControl, const FloatPoint& newEnd);
+    float cubicBezierTo(const FloatPoint& newControl1, const FloatPoint& newControl2, const FloatPoint& newEnd);
+
+public:
+    PathTraversalAction m_action;
+    bool m_success;
+
+    FloatPoint m_current;
+    FloatPoint m_start;
+    FloatPoint m_control1;
+    FloatPoint m_control2;
+
+    float m_totalLength;
+    unsigned m_segmentIndex;
+    float m_desiredLength;
+
+    // For normal calculations
+    FloatPoint m_previous;
+    float m_normalAngle; // degrees
+};    
 }
 
 #endif
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to