haikuwebkit/LayoutTests/svg/custom/pattern-content-inheritance...

57 lines
2.2 KiB
XML
Raw Permalink Normal View History

Exploitable crash happens when an SVG contains an indirect resource inheritance cycle https://bugs.webkit.org/show_bug.cgi?id=150203 Reviewed by Brent Fulgham. Source/WebCore: Detecting cycles in SVG resource references happens in two places. 1. In SVGResourcesCycleSolver::resolveCycles() which it is called from SVGResourcesCache::addResourcesFromRenderer(). When a cycle is deleted, SVGResourcesCycleSolver::breakCycle() is called to break the link. In the case of a cyclic resource inheritance, SVGResources::resetLinkedResource() is called to break this cycle. 2. SVGPatternElement::collectPatternAttributes() which is called from RenderSVGResourcePattern::buildPattern(). The purpose is to resolve the pattern attributes and to build a tile image which can be used to fill the SVG element renderer. Detecting the cyclic resource reference in this function is not sufficient and can detect simple cycles like <pattern id="a" xlink:href="#b"/> <pattern id="b" xlink:href="#a"/>. But it does not detect cycles like: <pattern id="a"> <rect fill="url(#b)"/> </pattern> <pattern id="b" xlink:href="#a"/>. The fix is to get rid of SVGPatternElement::collectPatternAttributes() which uses SVGURIReference::targetElementFromIRIString() to navigates through the referenced resource elements and tries to detect cycles. Instead we can implement RenderSVGResourcePattern::collectPatternAttributes() which calls SVGResourcesCache::cachedResourcesForRenderer() to get the SVGResources of the pattern. Then we use SVGResources::linkedResource() to navigate the resource inheritance tree. The cached SVGResources is guaranteed to be free of cycles. Tests: svg/custom/pattern-content-inheritance-cycle.svg * rendering/svg/RenderSVGResourcePattern.cpp: (WebCore::RenderSVGResourcePattern::collectPatternAttributes): Collect the pattern attributes through the cachedResourcesForRenderer(). (WebCore::RenderSVGResourcePattern::buildPattern): Direct the call to the renderer function. * rendering/svg/RenderSVGResourcePattern.h: * rendering/svg/RenderSVGRoot.cpp: (WebCore::RenderSVGRoot::layout): RenderSVGRoot needs to call SVGResourcesCache::clientStyleChanged() for all the invalidated resources. If an attribute of an SVG resource was updated dynamically, the cached SVGResources associated with the renderer of this resource was stale. * rendering/svg/SVGRenderTreeAsText.cpp: (WebCore::writeSVGResourceContainer): Direct the call to the renderer function. * svg/SVGPatternElement.cpp: (WebCore::SVGPatternElement::collectPatternAttributes): (WebCore::setPatternAttributes): Deleted. collectPatternAttributes() is a replacement of setPatternAttributes(). LayoutTests: Ensure that we do not crash when an SVG has an indirect cyclic resource inheritance. Make sure the cyclic resource was just ignored as if it did not exist. * svg/custom/pattern-content-inheritance-cycle-expected.svg: Added. * svg/custom/pattern-content-inheritance-cycle.svg: Added. Canonical link: https://commits.webkit.org/168837@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@191731 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-10-29 17:12:43 +00:00
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<!-- a => b => a -->
<pattern id="a" x="0" y="0" width=".25" height=".25">
<rect fill="lime" width="100%" height="100%"/>
<rect fill="url(#b)" width="100%" height="100%"/>
</pattern>
<pattern id="b" xlink:href="#a"/>
<!-- l => m => n => l -->
<pattern id="l" x="0" y="0" width=".25" height=".25">
<rect fill="lime" width="100%" height="100%"/>
<rect fill="url(#m)" width="100%" height="100%"/>
</pattern>
<pattern id="m" xlink:href="#n"/>
<pattern id="n" xlink:href="#l"/>
<!-- p => q -->
<pattern id="p" x="0" y="0" width=".25" height=".25">
<rect fill="lime" width="100%" height="100%"/>
<rect fill="url(#q)" width="100%" height="100%"/>
</pattern>
<pattern id="q"/>
<!-- t => s -->
<pattern id="s" x="0" y="0" width=".25" height=".25">
<rect fill="lime" width="100%" height="100%"/>
<rect id="r" width="100%" height="100%"/>
</pattern>
<pattern id="t" xlink:href="#s"/>
</defs>
<g fill="none" stroke="black" stroke-width="1">
<circle cx="75" cy="75" fill="url(#a)" r="50"/>
<circle cx="200" cy="75" fill="url(#b)" r="50"/>
<circle cx="75" cy="200" fill="url(#l)" r="50"/>
<circle cx="200" cy="200" fill="url(#m)" r="50"/>
<circle cx="325" cy="200" fill="url(#n)" r="50"/>
<circle cx="75" cy="325" fill="url(#p)" r="50"/>
<circle cx="200" cy="325" fill="url(#q)" r="50"/>
<circle cx="75" cy="450" fill="url(#s)" r="50"/>
<circle cx="200" cy="450" fill="url(#t)" r="50"/>
</g>
<script>
// Add q => p to get p => q => p
document.getElementById("q").setAttributeNS("http://www.w3.org/1999/xlink", "href", "#p");
// Add s => t to get s => t => s
document.getElementById("r").setAttribute("fill", "url(#t)");
// Force layout
document.documentElement.removeAttribute("class");
</script>
</svg>