Source/WebCore: Crash due to bad data in SVGDocumentExtensions m_pendingResources

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

Patch by Ken Buchanan <kenrb@chromium.org> on 2011-09-10
Reviewed by Nikolas Zimmermann.

Resolving a crash condition caused by the deletion of
elements while pending resource entries for those elements are still
recorded.

* rendering/svg/RenderSVGResourceContainer.cpp:
(WebCore::RenderSVGResourceContainer::registerResource)
* svg/SVGDocumentExtensions.h:
(WebCore::SVGDocumentExtensions::isElementInPendingResources)
* svg/SVGDocumentExtensions.cpp:
(WebCore::SVGDocumentExtensions::addPendingResource)
(WebCore::SVGDocumentExtensions::isElementInPendingResources)
(WebCore::SVGDocumentExtensions::removeElementFromPendingResources)
* svg/SVGStyledElement.h:
(WebCore::SVGStyledElement::clearHasPendingResourcesIfPossible)
* svg/SVGStyledElement.cpp:
(WebCore::SVGStyledElement::buildPendingResourcesIfNeeded)
(WebCore::SVGStyledElement::clearHasPendingResourcesIfPossible)
* svg/SVGUseElement.cpp:
(WebCore::SVGUseElement::svgAttributeChanged)

LayoutTests: Crash due to bad data in SVGDocumentExtensions m_pendingResources.
https://bugs.webkit.org/show_bug.cgi?id=67488

Patch by Ken Buchanan <kenrb@chromium.org> on 2011-09-10
Reviewed by Nikolas Zimmermann.

Test added: validating that the crash referenced in the bug is not present.

* svg/dom/SVGStyledElement-pendingResource-crash.html: Added.
* svg/dom/SVGStyledElement-pendingResource-crash-expected.txt: Added.
* svg/dom/resources/SVGStyledElement-pendingResource-crash.svg: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@94905 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent b6104dff
2011-09-10 Ken Buchanan <kenrb@chromium.org>
Crash due to bad data in SVGDocumentExtensions m_pendingResources.
https://bugs.webkit.org/show_bug.cgi?id=67488
Reviewed by Nikolas Zimmermann.
Test added: validating that the crash referenced in the bug is not present.
* svg/dom/SVGStyledElement-pendingResource-crash.html: Added.
* svg/dom/SVGStyledElement-pendingResource-crash-expected.txt: Added.
* svg/dom/resources/SVGStyledElement-pendingResource-crash.svg: Added.
2011-09-09 Erik Arvidsson <arv@chromium.org>
Move Element.contains to Node
PASS, if DumpRenderTree doesn't crash, and no assertion in a Debug build.
<!DOCTYPE html>
<html >
<script>
function body_start() {
var q = document.getElementById('root').contentDocument;
q.getElementsByTagName('svg')[0].replaceChild(q.getElementById('refImage'), q.getElementById('d'));
q.getElementsByTagName('use')[0].setAttribute('xlink:href', '#testName');
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.waitUntilDone();
}
setTimeout(function () {
document.body.innerHTML = "PASS, if DumpRenderTree doesn't crash, and no assertion in a Debug build.";
if (window.layoutTestController)
layoutTestController.notifyDone();
}, 0);
}
</script>
<object data="resources/SVGStyledElement-pendingResource-crash.svg" id="root" onload="body_start();" type="image/svg+xml"/></object>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<image id="refImage"/>
<g>
<text id="testName">X</text>
<use xlink:href="#navigationGroup" />
</g>
<defs id="d">
<g id="navigationGroup" fill='url(#testName)'>
<a stroke='url(#refImage)'><text id="ABC">A</text></a>
</g>
</defs>
</svg>
2011-09-10 Ken Buchanan <kenrb@chromium.org>
Crash due to bad data in SVGDocumentExtensions m_pendingResources
https://bugs.webkit.org/show_bug.cgi?id=67488
Reviewed by Nikolas Zimmermann.
Resolving a crash condition caused by the deletion of
elements while pending resource entries for those elements are still
recorded.
* rendering/svg/RenderSVGResourceContainer.cpp:
(WebCore::RenderSVGResourceContainer::registerResource)
* svg/SVGDocumentExtensions.h:
(WebCore::SVGDocumentExtensions::isElementInPendingResources)
* svg/SVGDocumentExtensions.cpp:
(WebCore::SVGDocumentExtensions::addPendingResource)
(WebCore::SVGDocumentExtensions::isElementInPendingResources)
(WebCore::SVGDocumentExtensions::removeElementFromPendingResources)
* svg/SVGStyledElement.h:
(WebCore::SVGStyledElement::clearHasPendingResourcesIfPossible)
* svg/SVGStyledElement.cpp:
(WebCore::SVGStyledElement::buildPendingResourcesIfNeeded)
(WebCore::SVGStyledElement::clearHasPendingResourcesIfPossible)
* svg/SVGUseElement.cpp:
(WebCore::SVGUseElement::svgAttributeChanged)
2011-09-10 Adam Barth <abarth@webkit.org>
Remove DocumentWriter::deprecatedFrameEncoding()
......@@ -168,7 +168,7 @@ void RenderSVGResourceContainer::registerResource()
const SVGDocumentExtensions::SVGPendingElements::const_iterator end = clients->end();
for (SVGDocumentExtensions::SVGPendingElements::const_iterator it = clients->begin(); it != end; ++it) {
ASSERT((*it)->hasPendingResources());
(*it)->setHasPendingResources(false);
(*it)->clearHasPendingResourcesIfPossible();
RenderObject* renderer = (*it)->renderer();
if (!renderer)
continue;
......
......@@ -227,7 +227,7 @@ void SVGDocumentExtensions::addPendingResource(const AtomicString& id, SVGStyled
m_pendingResources.add(id, set);
}
element->setHasPendingResources(true);
element->setHasPendingResources();
}
bool SVGDocumentExtensions::hasPendingResources(const AtomicString& id) const
......@@ -238,6 +238,24 @@ bool SVGDocumentExtensions::hasPendingResources(const AtomicString& id) const
return m_pendingResources.contains(id);
}
bool SVGDocumentExtensions::isElementInPendingResources(SVGStyledElement* element) const
{
ASSERT(element);
if (m_pendingResources.isEmpty())
return false;
HashMap<AtomicString, SVGPendingElements*>::const_iterator end = m_pendingResources.end();
for (HashMap<AtomicString, SVGPendingElements*>::const_iterator it = m_pendingResources.begin(); it != end; ++it) {
SVGPendingElements* elements = it->second;
ASSERT(elements);
if (elements->contains(element))
return true;
}
return false;
}
void SVGDocumentExtensions::removeElementFromPendingResources(SVGStyledElement* element)
{
ASSERT(element);
......@@ -245,8 +263,6 @@ void SVGDocumentExtensions::removeElementFromPendingResources(SVGStyledElement*
if (m_pendingResources.isEmpty() || !element->hasPendingResources())
return;
element->setHasPendingResources(false);
Vector<AtomicString> toBeRemoved;
HashMap<AtomicString, SVGPendingElements*>::iterator end = m_pendingResources.end();
for (HashMap<AtomicString, SVGPendingElements*>::iterator it = m_pendingResources.begin(); it != end; ++it) {
......@@ -259,6 +275,8 @@ void SVGDocumentExtensions::removeElementFromPendingResources(SVGStyledElement*
toBeRemoved.append(it->first);
}
element->clearHasPendingResourcesIfPossible();
if (toBeRemoved.isEmpty())
return;
......
......@@ -81,6 +81,7 @@ public:
// For instance, dynamically build gradients / patterns / clippers...
void addPendingResource(const AtomicString& id, SVGStyledElement*);
bool hasPendingResources(const AtomicString& id) const;
bool isElementInPendingResources(SVGStyledElement*) const;
void removeElementFromPendingResources(SVGStyledElement*);
PassOwnPtr<SVGPendingElements> removePendingResource(const AtomicString& id);
};
......
......@@ -389,7 +389,7 @@ void SVGStyledElement::buildPendingResourcesIfNeeded()
for (SVGDocumentExtensions::SVGPendingElements::const_iterator it = clients->begin(); it != end; ++it) {
ASSERT((*it)->hasPendingResources());
(*it)->buildPendingResource();
(*it)->setHasPendingResources(false);
(*it)->clearHasPendingResourcesIfPossible();
}
}
......@@ -456,9 +456,15 @@ bool SVGStyledElement::hasPendingResources() const
return hasRareSVGData() && rareSVGData()->hasPendingResources();
}
void SVGStyledElement::setHasPendingResources(bool value)
void SVGStyledElement::setHasPendingResources()
{
ensureRareSVGData()->setHasPendingResources(value);
ensureRareSVGData()->setHasPendingResources(true);
}
void SVGStyledElement::clearHasPendingResourcesIfPossible()
{
if (!document()->accessSVGExtensions()->isElementInPendingResources(this))
ensureRareSVGData()->setHasPendingResources(false);
}
AffineTransform SVGStyledElement::localCoordinateSpaceTransform(SVGLocatable::CTMScope) const
......
......@@ -50,7 +50,8 @@ public:
void setInstanceUpdatesBlocked(bool);
bool hasPendingResources() const;
void setHasPendingResources(bool);
void setHasPendingResources();
void clearHasPendingResourcesIfPossible();
virtual void animatedPropertyTypeForAttribute(const QualifiedName&, Vector<AnimatedPropertyType>&);
static bool isAnimatableCSSProperty(const QualifiedName&);
......
......@@ -204,11 +204,11 @@ void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName)
const SVGDocumentExtensions::SVGPendingElements::const_iterator end = clients->end();
for (SVGDocumentExtensions::SVGPendingElements::const_iterator it = clients->begin(); it != end; ++it) {
ASSERT((*it)->hasPendingResources());
(*it)->setHasPendingResources(false);
(*it)->clearHasPendingResourcesIfPossible();
}
m_resourceId = String();
setHasPendingResources(false);
clearHasPendingResourcesIfPossible();
}
m_targetElementInstance = 0;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment