diff --git a/content/svg/content/src/SVGPathData.cpp b/content/svg/content/src/SVGPathData.cpp index e8f16ccd894..67cab0228f8 100644 --- a/content/svg/content/src/SVGPathData.cpp +++ b/content/svg/content/src/SVGPathData.cpp @@ -554,9 +554,9 @@ SVGPathData::GetMarkerPositioningData(nsTArray *aMarks) const case nsIDOMSVGPathSeg::PATHSEG_ARC_ABS: case nsIDOMSVGPathSeg::PATHSEG_ARC_REL: { - float rx = mData[i]; - float ry = mData[i+1]; - float angle = mData[i+2]; + double rx = mData[i]; + double ry = mData[i+1]; + double angle = mData[i+2]; PRBool largeArcFlag = mData[i+3] != 0.0f; PRBool sweepFlag = mData[i+4] != 0.0f; if (segType == nsIDOMSVGPathSeg::PATHSEG_ARC_ABS) { @@ -595,46 +595,47 @@ SVGPathData::GetMarkerPositioningData(nsTArray *aMarks) const // F.6.5.1: angle = angle * M_PI/180.0; - float x1p = cos(angle) * (segStart.x - segEnd.x) / 2.0 - + sin(angle) * (segStart.y - segEnd.y) / 2.0; - float y1p = -sin(angle) * (segStart.x - segEnd.x) / 2.0 - + cos(angle) *(segStart.y - segEnd.y) / 2.0; + double x1p = cos(angle) * (segStart.x - segEnd.x) / 2.0 + + sin(angle) * (segStart.y - segEnd.y) / 2.0; + double y1p = -sin(angle) * (segStart.x - segEnd.x) / 2.0 + + cos(angle) * (segStart.y - segEnd.y) / 2.0; // This is the root in F.6.5.2 and the numerator under that root: - float root; - float numerator = rx*rx*ry*ry - rx*rx*y1p*y1p - ry*ry*x1p*x1p; + double root; + double numerator = rx*rx*ry*ry - rx*rx*y1p*y1p - ry*ry*x1p*x1p; - if (numerator < 0.0) { - // F.6.6 step 3 - |numerator < 0.0| is equivalent to the result of - // F.6.6.2 (lamedh) being greater than one. What we have here is radii - // that do not reach between segStart and segEnd, so we need to correct - // them. - float lamedh = 1.0 - numerator/(rx*rx*ry*ry); // equiv to eqn F.6.6.2 - float s = sqrt(lamedh); + if (numerator >= 0.0) { + root = sqrt(numerator/(rx*rx*y1p*y1p + ry*ry*x1p*x1p)); + if (largeArcFlag == sweepFlag) + root = -root; + } else { + // F.6.6 step 3 - |numerator < 0.0|. This is equivalent to the result + // of F.6.6.2 (lamedh) being greater than one. What we have here is + // ellipse radii that are too small for the ellipse to reach between + // segStart and segEnd. We scale the radii up uniformly so that the + // ellipse is just big enough to fit (i.e. to the point where there is + // exactly one solution). + + double lamedh = 1.0 - numerator/(rx*rx*ry*ry); // equiv to eqn F.6.6.2 + double s = sqrt(lamedh); rx *= s; // F.6.6.3 ry *= s; - // rx and ry changed, so we have to recompute numerator - numerator = rx*rx*ry*ry - rx*rx*y1p*y1p - ry*ry*x1p*x1p; - NS_ABORT_IF_FALSE(numerator >= 0, - "F.6.6.3 should prevent this. Will sqrt(-num)!"); + root = 0.0; } - root = sqrt(numerator/(rx*rx*y1p*y1p + ry*ry*x1p*x1p)); - if (largeArcFlag == sweepFlag) - root = -root; - float cxp = root * rx * y1p / ry; // F.6.5.2 - float cyp = -root * ry * x1p / rx; + double cxp = root * rx * y1p / ry; // F.6.5.2 + double cyp = -root * ry * x1p / rx; - float theta, delta; - theta = CalcVectorAngle(1.0, 0.0, (x1p-cxp)/rx, (y1p-cyp)/ry); // F.6.5.5 - delta = CalcVectorAngle((x1p-cxp)/rx, (y1p-cyp)/ry, - (-x1p-cxp)/rx, (-y1p-cyp)/ry); // F.6.5.6 + double theta, delta; + theta = CalcVectorAngle(1.0, 0.0, (x1p-cxp)/rx, (y1p-cyp)/ry); // F.6.5.5 + delta = CalcVectorAngle((x1p-cxp)/rx, (y1p-cyp)/ry, + (-x1p-cxp)/rx, (-y1p-cyp)/ry); // F.6.5.6 if (!sweepFlag && delta > 0) delta -= 2.0 * M_PI; else if (sweepFlag && delta < 0) delta += 2.0 * M_PI; - float tx1, ty1, tx2, ty2; + double tx1, ty1, tx2, ty2; tx1 = -cos(angle)*rx*sin(theta) - sin(angle)*ry*cos(theta); ty1 = -sin(angle)*rx*sin(theta) + cos(angle)*ry*cos(theta); tx2 = -cos(angle)*rx*sin(theta+delta) - sin(angle)*ry*cos(theta+delta); diff --git a/layout/svg/crashtests/610594-1.html b/layout/svg/crashtests/610594-1.html new file mode 100644 index 00000000000..ee48e762ccb --- /dev/null +++ b/layout/svg/crashtests/610594-1.html @@ -0,0 +1,6 @@ + + + + + + diff --git a/layout/svg/crashtests/crashtests.list b/layout/svg/crashtests/crashtests.list index c894598021e..4eea0923972 100644 --- a/layout/svg/crashtests/crashtests.list +++ b/layout/svg/crashtests/crashtests.list @@ -97,7 +97,9 @@ load 587336-1.html load 590291-1.svg load 601999-1.html load 605626-1.svg +load 610594-1.html load 610954-1.html load 612662-1.svg load 612662-2.svg + load 621598-1.svg