Bug 740627 - Fix assert if width/height of pattern is negative. r=dholbert
☠☠ backed out by 2195f743e7dc ☠ ☠
authorRobert Longson <longsonr@gmail.com>
Sat, 31 Mar 2012 11:47:18 +0100
changeset 94091 a329aa4bc02608f8eda463dcbddd75f342865f37
parent 94090 5a5a55d435ca2bc3ba65fa606d620e1033932b55
child 94092 2195f743e7dcb69f975a2b557baacb4d74b98b17
push id886
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 19:57:52 +0000
treeherdermozilla-beta@bbd8d5efd6d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs740627
milestone14.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 740627 - Fix assert if width/height of pattern is negative. r=dholbert
layout/svg/base/src/nsSVGPatternFrame.cpp
layout/svg/crashtests/740627-1.svg
layout/svg/crashtests/740627-2.svg
layout/svg/crashtests/crashtests.list
--- a/layout/svg/base/src/nsSVGPatternFrame.cpp
+++ b/layout/svg/base/src/nsSVGPatternFrame.cpp
@@ -575,20 +575,24 @@ nsSVGPatternFrame::ConstructCTM(const gf
   } else {
     if (targetContent->IsSVG()) {
       ctx = static_cast<nsSVGElement*>(targetContent)->GetCtx();
     }
     float scale = nsSVGUtils::MaxExpansion(callerCTM);
     tCTM.Scale(scale, scale);
   }
 
-  const nsSVGViewBoxRect viewBox = GetViewBox().GetAnimValue();
+  const nsSVGViewBox& viewBox = GetViewBox();
+  if (!viewBox.IsValid()) {
+    return tCTM;
+  }
+  const nsSVGViewBoxRect viewBoxRect = GetViewBox().GetAnimValue();
 
-  if (viewBox.height <= 0.0f || viewBox.width <= 0.0f) {
-    return tCTM;
+  if (viewBoxRect.height <= 0.0f || viewBoxRect.width <= 0.0f) {
+    return gfxMatrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // singular
   }
 
   float viewportWidth, viewportHeight;
   if (targetContent->IsSVG()) {
     // If we're dealing with an SVG target only retrieve the context once.
     // Calling the nsIFrame* variant of GetAnimValue would look it up on
     // every call.
     viewportWidth =
@@ -597,21 +601,26 @@ nsSVGPatternFrame::ConstructCTM(const gf
       GetLengthValue(nsSVGPatternElement::HEIGHT)->GetAnimValue(ctx);
   } else {
     // No SVG target, call the nsIFrame* variant of GetAnimValue.
     viewportWidth =
       GetLengthValue(nsSVGPatternElement::WIDTH)->GetAnimValue(aTarget);
     viewportHeight =
       GetLengthValue(nsSVGPatternElement::HEIGHT)->GetAnimValue(aTarget);
   }
+
+  if (viewportWidth <= 0.0f || viewportHeight <= 0.0f) {
+    return gfxMatrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // singular
+  }
+
   gfxMatrix tm = nsSVGUtils::GetViewBoxTransform(
     static_cast<nsSVGPatternElement*>(mContent),
     viewportWidth, viewportHeight,
-    viewBox.x, viewBox.y,
-    viewBox.width, viewBox.height,
+    viewBoxRect.x, viewBoxRect.y,
+    viewBoxRect.width, viewBoxRect.height,
     GetPreserveAspectRatio());
 
   return tm * tCTM;
 }
 
 // Given the matrix for the pattern element's own transform, this returns a
 // combined matrix including the transforms applicable to its target.
 gfxMatrix
new file mode 100644
--- /dev/null
+++ b/layout/svg/crashtests/740627-1.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+  <pattern id="test" viewBox="0 0 10 10" height="-65%">
+    <rect/>
+  </pattern>
+  <rect width="100" height="100" fill="url(#test)"/>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/svg/crashtests/740627-2.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+  <pattern id="test" viewBox="0 0 10 10" width="-65%">
+    <rect/>
+  </pattern>
+  <rect width="100" height="100" fill="url(#test)"/>
+</svg>
--- a/layout/svg/crashtests/crashtests.list
+++ b/layout/svg/crashtests/crashtests.list
@@ -120,8 +120,10 @@ load 692203-1.svg
 load 692203-2.svg
 load 693424-1.svg
 load 709920-1.svg
 load 709920-2.svg
 load 713413-1.svg
 load 722003-1.svg
 load 725918-1.svg
 load 732836-1.svg
+load 740627-1.svg
+load 740627-2.svg