Bug 587336: Keep nsSVGIntegrationUtils::GetInvalidAreaForChangedSource from inadvertantly adding an observer relationship and potentially triggering an infinite loop a few stack-levels up. r=roc a=blocking-final+
authorDaniel Holbert <dholbert@cs.stanford.edu>
Tue, 09 Nov 2010 21:50:29 -0800
changeset 57190 c7726ff56cbf49b5f93d901b712625d91a3afab3
parent 57189 3dac4e7101577acefa7cb2035aff6be9b87e5d69
child 57191 fa47bfaec680a4b01a99f72a46ac8b5056afac86
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersroc, blocking-final
bugs587336
milestone2.0b8pre
Bug 587336: Keep nsSVGIntegrationUtils::GetInvalidAreaForChangedSource from inadvertantly adding an observer relationship and potentially triggering an infinite loop a few stack-levels up. r=roc a=blocking-final+
layout/svg/base/src/nsSVGEffects.h
layout/svg/base/src/nsSVGIntegrationUtils.cpp
layout/svg/crashtests/587336-1.html
layout/svg/crashtests/crashtests.list
--- a/layout/svg/base/src/nsSVGEffects.h
+++ b/layout/svg/base/src/nsSVGEffects.h
@@ -76,16 +76,17 @@ public:
   // nsIMutationObserver
   NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
 
   void InvalidateViaReferencedElement();
   nsIFrame* GetReferencedFrame();
+  PRBool IsInObserverList() const { return mInObserverList; }
 
   /**
    * @param aOK this is only for the convenience of callers. We set *aOK to false
    * if this function returns null.
    */
   nsIFrame* GetReferencedFrame(nsIAtom* aFrameType, PRBool* aOK);
 
   Element* GetReferencedElement();
--- a/layout/svg/base/src/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/base/src/nsSVGIntegrationUtils.cpp
@@ -142,17 +142,23 @@ nsSVGIntegrationUtils::GetInvalidAreaFor
   // Don't bother calling GetEffectProperties; the filter property should
   // already have been set up during reflow/ComputeFrameEffectsRect
   nsIFrame* firstFrame =
     nsLayoutUtils::GetFirstContinuationOrSpecialSibling(aFrame);
   nsSVGEffects::EffectProperties effectProperties =
     nsSVGEffects::GetEffectProperties(firstFrame);
   if (!effectProperties.mFilter)
     return aInvalidRect;
-  nsSVGFilterFrame* filterFrame = nsSVGEffects::GetFilterFrame(firstFrame);
+
+  nsSVGFilterProperty *prop = nsSVGEffects::GetFilterProperty(aFrame);
+  if (!prop || !prop->IsInObserverList()) {
+    return aInvalidRect;
+  }
+
+  nsSVGFilterFrame* filterFrame = prop->GetFilterFrame();
   if (!filterFrame) {
     // The frame is either not there or not currently available,
     // perhaps because we're in the middle of tearing stuff down.
     // Be conservative.
     return aFrame->GetVisualOverflowRect();
   }
 
   PRInt32 appUnitsPerDevPixel = aFrame->PresContext()->AppUnitsPerDevPixel();
new file mode 100644
--- /dev/null
+++ b/layout/svg/crashtests/587336-1.html
@@ -0,0 +1,9 @@
+<html>
+<head><script>
+function boom()
+{
+  var b = document.getElementById("b");
+  b.setAttributeNS(null, "style", "filter: url(#a);");
+}
+</script></head>
+<body onload="boom();" id="a"><span id="b">B</span></body></html>
--- a/layout/svg/crashtests/crashtests.list
+++ b/layout/svg/crashtests/crashtests.list
@@ -85,13 +85,14 @@ load 478511-1.svg
 load 483439-1.svg
 load 492186-1.svg
 load 508247-1.svg
 load 512890-1.svg
 load 515288-1.html
 load 522394-1.svg
 load 522394-2.svg
 load 522394-3.svg
-load 590291-1.svg
 load extref-test-1.xhtml
 load 566216-1.svg
+load 587336-1.html
+load 590291-1.svg
 load 601999-1.html
 load 605626-1.svg