[Webkit-unassigned] [Bug 35688] New: expandUseElementsInShadowTree infinite recursion stack exhaustion.

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Wed Mar 3 07:54:38 PST 2010


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

           Summary: expandUseElementsInShadowTree infinite recursion stack
                    exhaustion.
           Product: WebKit
           Version: 528+ (Nightly build)
          Platform: PC
               URL: http://code.google.com/p/chromium/issues/detail?id=372
                    87
        OS/Version: Windows Vista
            Status: NEW
          Severity: Normal
          Priority: P3
         Component: SVG
        AssignedTo: webkit-unassigned at lists.webkit.org
        ReportedBy: skylined at chromium.org
                CC: eric at webkit.org


Repro:
  <svg xmlns="http://www.w3.org/2000/svg">
  <g id="foo">
  <svg xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xl="http://www.w3.org/1999/xlink">
  <use xl:href="#foo"/>
  <g id="bar" />
  <use xlink:href="#bar" />

This causes infinite recursion in expandUseElementsInShadowTree, which leads to
stack exhaustion. Below is the code, as you can see, it calls itself in two
locations. The 
bottom one seems to be the culprit in this case:

http://svn.webkit.org/repository/webkit/trunk/WebCore/svg/SVGUseElement.cpp?r=55462
void SVGUseElement::expandUseElementsInShadowTree(SVGShadowTreeRootElement*
shadowRoot, Node* element)
{
    // Why expand the <use> elements in the shadow tree here, and not just
    // do this directly in buildShadowTree, if we encounter a <use> element?
    //
    // Short answer: Because we may miss to expand some elements. Ie. if a
<symbol>
    // contains <use> tags, we'd miss them. So once we're done with settin' up
the
    // actual shadow tree (after the special case modification for svg/symbol)
we have
    // to walk it completely and expand all <use> elements.
    if (element->hasTagName(SVGNames::useTag)) {
        SVGUseElement* use = static_cast<SVGUseElement*>(element);

        String id = SVGURIReference::getTarget(use->href());
        Element* targetElement = document()->getElementById(id); 
        SVGElement* target = 0;
        if (targetElement && targetElement->isSVGElement())
            target = static_cast<SVGElement*>(targetElement);

        // Don't ASSERT(target) here, it may be "pending", too.
        if (target) {
            // Setup sub-shadow tree root node
            RefPtr<SVGShadowTreeContainerElement> cloneParent = new
SVGShadowTreeContainerElement(document());

            // 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.
            transferUseAttributesToReplacedElement(use, cloneParent.get());

            ExceptionCode ec = 0;

            // For instance <use> on <foreignObject> (direct case).
            if (isDisallowedElement(target)) {
                // We still have to setup the <use> replacment (<g>).
Otherwhise
                // associateInstancesWithShadowTreeElements() makes wrong
assumptions.
                // Replace <use> with referenced content.
                ASSERT(use->parentNode()); 
                use->parentNode()->replaceChild(cloneParent.release(), use,
ec);
                ASSERT(!ec);
                return;
            }

            RefPtr<Element> newChild = target->cloneElementWithChildren();

            // We don't walk the target tree element-by-element, and clone each
element,
            // but instead use cloneElementWithChildren(). This is an
optimization for the common
            // case where <use> doesn't contain disallowed elements (ie.
<foreignObject>).
            // Though if there are disallowed elements in the subtree, we have
to remove them.
            // For instance: <use> on <g> containing <foreignObject> (indirect
case).
            if (subtreeContainsDisallowedElement(newChild.get()))
                removeDisallowedElementsFromSubtree(newChild.get());

            SVGElement* newChildPtr = 0;
            if (newChild->isSVGElement())
                newChildPtr = static_cast<SVGElement*>(newChild.get());
            ASSERT(newChildPtr);

            cloneParent->appendChild(newChild.release(), ec);
            ASSERT(!ec);

            // Replace <use> with referenced content.
            ASSERT(use->parentNode()); 
            use->parentNode()->replaceChild(cloneParent.release(), use, ec);
            ASSERT(!ec);

            // Immediately stop here, and restart expanding.
            expandUseElementsInShadowTree(shadowRoot, shadowRoot);
            return;
        }
    }

    for (RefPtr<Node> child = element->firstChild(); child; child =
child->nextSibling())
        expandUseElementsInShadowTree(shadowRoot, child.get());
}

-- 
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