- 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