[Webkit-unassigned] [Bug 42079] New: SVG Large curve path segment OOM crash

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Mon Jul 12 07:44:33 PDT 2010


https://bugs.webkit.org/show_bug.cgi?id=42079

           Summary: SVG Large curve path segment OOM crash
           Product: WebKit
           Version: 528+ (Nightly build)
          Platform: PC
               URL: http://code.google.com/p/chromium/issues/detail?id=488
                    34
        OS/Version: Windows Vista
            Status: NEW
          Severity: Normal
          Priority: P1
         Component: SVG
        AssignedTo: webkit-unassigned at lists.webkit.org
        ReportedBy: skylined at chromium.org
                CC: eric at webkit.org, zimmermann at kde.org


Code for determining SVG path lengths does not handle very large curves well: when calculating the length of a curve, it attempts to split up a large curve into smaller curves. Each split causes extra memory to be allocated and large curves require several splits. This can leads to OOM and a renderer crash in Chromium, but it does not appear to affect Safari.

Repro:
<script>
  var path = document.createElementNS("http://www.w3.org/2000/svg", "path");
  // Large values cause a large curve:
  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.insertItemBefore(pathSeg, 0);
  path.getPointAtLength();
</script>

Code:
http://trac.webkit.org/browser/trunk/WebCore/platform/graphics/PathTraversalState.cpp#L119
119    template<class CurveType>
120    static float curveLength(PathTraversalState& traversalState, CurveType curve)
121    {
122        Vector<CurveType> curveStack;
123        curveStack.append(curve);
124    
125        float totalLength = 0.0f;
126        do {
127            float length = curve.approximateDistance();
// If the curve is large, split it and handle each part separately:
128            if ((length - distanceLine(curve.start, curve.end)) > kPathSegmentLengthTolerance) {
129                CurveType left, right;
130                curve.split(left, right);
131                curve = left;
132                curveStack.append(right);
// If both left and right are still very large, they will get split as well, and again, and again, etc...
133            } else {
134                totalLength += length;
135                if (traversalState.m_action == PathTraversalState::TraversalPointAtLength
136                 || traversalState.m_action == PathTraversalState::TraversalNormalAngleAtLength) {
137                    traversalState.m_previous = curve.start;
138                    traversalState.m_current = curve.end;
139                    if (traversalState.m_totalLength + totalLength > traversalState.m_desiredLength)
140                        return totalLength;
141                }
142                curve = curveStack.last();
143                curveStack.removeLast();
144            }
145        } while (!curveStack.isEmpty());
146       
147        return totalLength;
148    }
Luckily, we detect the OOM and crash the renderer cleanly with an int3 on line 132.

-- 
Configure bugmail: https://bugs.webkit.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.



More information about the webkit-unassigned mailing list