REGRESSION (r179101): SVGUseElement::expandUseElementsInShadowTree has an object...
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 27 Jan 2015 04:39:58 +0000 (04:39 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 27 Jan 2015 04:39:58 +0000 (04:39 +0000)
https://bugs.webkit.org/show_bug.cgi?id=140921

Reviewed by Alexey Proskuryakov.

Bug found by running regression tests with Address Sanitizer.

* svg/SVGUseElement.cpp:
(WebCore::SVGUseElement::expandUseElementsInShadowTree): Use a Ref to protect
the original use element after it's been replaced in the tree; we use it for
one more thing after that.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@179163 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/svg/SVGUseElement.cpp

index fb66d4ff9d5c47fd73799eb2b6939b8276560129..e9e006436e91972a6ccb503fd898e7b9fcbab958 100644 (file)
@@ -1,3 +1,17 @@
+2015-01-26  Darin Adler  <darin@apple.com>
+
+        REGRESSION (r179101): SVGUseElement::expandUseElementsInShadowTree has an object lifetime mistake
+        https://bugs.webkit.org/show_bug.cgi?id=140921
+
+        Reviewed by Alexey Proskuryakov.
+
+        Bug found by running regression tests with Address Sanitizer.
+
+        * svg/SVGUseElement.cpp:
+        (WebCore::SVGUseElement::expandUseElementsInShadowTree): Use a Ref to protect
+        the original use element after it's been replaced in the tree; we use it for
+        one more thing after that.
+
 2015-01-26  Roger Fong  <roger_fong@apple.com>
 
         WebGL 2.0: Actually allow for experimental-webgl2 context creation.
index 23b0d1ac349ff4982ec7cf522da57b44c00959d6..a220a78de2381d939040334ff369aa502b5656b3 100644 (file)
@@ -609,10 +609,10 @@ void SVGUseElement::expandUseElementsInShadowTree()
     auto descendants = descendantsOfType<SVGUseElement>(*userAgentShadowRoot());
     auto end = descendants.end();
     for (auto it = descendants.begin(); it != end; ) {
-        SVGUseElement& original = *it;
+        Ref<SVGUseElement> original = *it;
         it = end; // Efficiently quiets assertions due to the outstanding iterator.
 
-        ASSERT(!original.cachedDocumentIsStillLoading());
+        ASSERT(!original->cachedDocumentIsStillLoading());
 
         // Spec: In the generated content, the 'use' will be replaced by 'g', where all attributes from the
         // 'use' element except for x, y, width, height and xlink:href are transferred to the generated 'g' element.
@@ -623,11 +623,11 @@ void SVGUseElement::expandUseElementsInShadowTree()
         ASSERT(referencedDocument());
         auto replacement = SVGGElement::create(SVGNames::gTag, *referencedDocument());
 
-        original.transferAttributesToShadowTreeReplacement(replacement.get());
-        original.cloneChildNodes(replacement.ptr());
+        original->transferAttributesToShadowTreeReplacement(replacement.get());
+        original->cloneChildNodes(replacement.ptr());
 
         RefPtr<SVGElement> clonedTarget;
-        Element* targetCandidate = SVGURIReference::targetElementFromIRIString(original.href(), *referencedDocument());
+        Element* targetCandidate = SVGURIReference::targetElementFromIRIString(original->href(), *referencedDocument());
         if (is<SVGElement>(targetCandidate) && !isDisallowedElement(downcast<SVGElement>(*targetCandidate))) {
             SVGElement& originalTarget = downcast<SVGElement>(*targetCandidate);
             clonedTarget = static_pointer_cast<SVGElement>(originalTarget.cloneElementWithChildren(document()));
@@ -641,12 +641,12 @@ void SVGUseElement::expandUseElementsInShadowTree()
         removeDisallowedElementsFromSubtree(replacement.get());
 
         // Replace <use> with the <g> element we created.
-        original.parentNode()->replaceChild(replacement.ptr(), &original);
+        original->parentNode()->replaceChild(replacement.ptr(), original.ptr());
 
         // Call transferSizeAttributesToShadowTreeTargetClone after putting the cloned elements into the
         // shadow tree so it can use SVGElement::correspondingElement without triggering an assertion.
         if (clonedTarget)
-            original.transferSizeAttributesToShadowTreeTargetClone(*clonedTarget);
+            original->transferSizeAttributesToShadowTreeTargetClone(*clonedTarget);
 
         // Continue iterating from the <g> element since the <use> element was replaced.
         it = descendants.from(replacement.get());