Title: [193729] branches/safari-601.4-branch

Diff

Modified: branches/safari-601.4-branch/LayoutTests/ChangeLog (193728 => 193729)


--- branches/safari-601.4-branch/LayoutTests/ChangeLog	2015-12-08 08:42:52 UTC (rev 193728)
+++ branches/safari-601.4-branch/LayoutTests/ChangeLog	2015-12-08 08:44:09 UTC (rev 193729)
@@ -1,5 +1,23 @@
 2015-12-08  Babak Shafiei  <bshaf...@apple.com>
 
+        Merge r191731.
+
+    2015-10-29  Said Abou-Hallawa  <sabouhall...@apple.com>
+
+            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.
+
+            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.
+
+2015-12-08  Babak Shafiei  <bshaf...@apple.com>
+
         Merge r192604.
 
     2015-11-18  Jiewen Tan  <jiewen_...@apple.com>

Copied: branches/safari-601.4-branch/LayoutTests/svg/custom/pattern-content-inheritance-cycle-expected.svg (from rev 193709, branches/safari-601.1.46.60-branch/LayoutTests/svg/custom/pattern-content-inheritance-cycle-expected.svg) (0 => 193729)


--- branches/safari-601.4-branch/LayoutTests/svg/custom/pattern-content-inheritance-cycle-expected.svg	                        (rev 0)
+++ branches/safari-601.4-branch/LayoutTests/svg/custom/pattern-content-inheritance-cycle-expected.svg	2015-12-08 08:44:09 UTC (rev 193729)
@@ -0,0 +1,16 @@
+<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <g fill="none" stroke="black" stroke-width="1">
+        <circle cx="75" cy="75" fill="lime" r="50"/>
+        <circle cx="200" cy="75" fill="none" r="50"/>
+
+        <circle cx="75" cy="200" fill="lime" r="50"/>
+        <circle cx="200" cy="200" fill="none" r="50"/>
+        <circle cx="325" cy="200" fill="none" r="50"/>
+    
+        <circle cx="75" cy="325" fill="lime" r="50"/>
+        <circle cx="200" cy="325" fill="none" r="50"/>
+    
+        <circle cx="75" cy="450" fill="lime" r="50"/>
+        <circle cx="200" cy="450" fill="none" r="50"/>
+    </g>
+</svg>

Copied: branches/safari-601.4-branch/LayoutTests/svg/custom/pattern-content-inheritance-cycle.svg (from rev 193709, branches/safari-601.1.46.60-branch/LayoutTests/svg/custom/pattern-content-inheritance-cycle.svg) (0 => 193729)


--- branches/safari-601.4-branch/LayoutTests/svg/custom/pattern-content-inheritance-cycle.svg	                        (rev 0)
+++ branches/safari-601.4-branch/LayoutTests/svg/custom/pattern-content-inheritance-cycle.svg	2015-12-08 08:44:09 UTC (rev 193729)
@@ -0,0 +1,56 @@
+<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=""
+        
+        <!-- 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=""
+        <pattern id="n" xlink:href=""
+        
+        <!-- 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=""
+    </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>

Modified: branches/safari-601.4-branch/Source/WebCore/ChangeLog (193728 => 193729)


--- branches/safari-601.4-branch/Source/WebCore/ChangeLog	2015-12-08 08:42:52 UTC (rev 193728)
+++ branches/safari-601.4-branch/Source/WebCore/ChangeLog	2015-12-08 08:44:09 UTC (rev 193729)
@@ -1,5 +1,71 @@
 2015-12-08  Babak Shafiei  <bshaf...@apple.com>
 
+        Merge r191731.
+
+    2015-10-29  Said Abou-Hallawa  <sabouhall...@apple.com>
+
+            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.
+
+            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=""
+                <pattern id="b" xlink:href=""
+               But it does not detect cycles like:
+                <pattern id="a">
+                    <rect fill="url(#b)"/>
+                </pattern>
+                <pattern id="b" xlink:href=""
+
+            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().
+
+2015-12-08  Babak Shafiei  <bshaf...@apple.com>
+
         Merge r192604.
 
     2015-11-18  Jiewen Tan  <jiewen_...@apple.com>

Modified: branches/safari-601.4-branch/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp (193728 => 193729)


--- branches/safari-601.4-branch/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp	2015-12-08 08:42:52 UTC (rev 193728)
+++ branches/safari-601.4-branch/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp	2015-12-08 08:44:09 UTC (rev 193729)
@@ -54,6 +54,19 @@
     markClientForInvalidation(client, markForInvalidation ? RepaintInvalidation : ParentOnlyInvalidation);
 }
 
+void RenderSVGResourcePattern::collectPatternAttributes(PatternAttributes& attributes) const
+{
+    const RenderSVGResourcePattern* current = this;
+
+    while (current) {
+        const SVGPatternElement& pattern = current->patternElement();
+        pattern.collectPatternAttributes(attributes);
+
+        auto* resources = SVGResourcesCache::cachedResourcesForRenderer(*current);
+        current = resources ? downcast<RenderSVGResourcePattern>(resources->linkedResource()) : nullptr;
+    }
+}
+
 PatternData* RenderSVGResourcePattern::buildPattern(RenderElement& renderer, unsigned short resourceMode)
 {
     PatternData* currentData = m_patternMap.get(&renderer);
@@ -64,7 +77,7 @@
         patternElement().synchronizeAnimatedSVGAttribute(anyQName());
 
         m_attributes = PatternAttributes();
-        patternElement().collectPatternAttributes(m_attributes);
+        collectPatternAttributes(m_attributes);
         m_shouldCollectPatternAttributes = false;
     }
 

Modified: branches/safari-601.4-branch/Source/WebCore/rendering/svg/RenderSVGResourcePattern.h (193728 => 193729)


--- branches/safari-601.4-branch/Source/WebCore/rendering/svg/RenderSVGResourcePattern.h	2015-12-08 08:42:52 UTC (rev 193728)
+++ branches/safari-601.4-branch/Source/WebCore/rendering/svg/RenderSVGResourcePattern.h	2015-12-08 08:44:09 UTC (rev 193729)
@@ -53,6 +53,8 @@
 
     virtual RenderSVGResourceType resourceType() const override { return PatternResourceType; }
 
+    void collectPatternAttributes(PatternAttributes&) const;
+
 private:
     void element() const = delete;
     virtual const char* renderName() const override { return "RenderSVGResourcePattern"; }

Modified: branches/safari-601.4-branch/Source/WebCore/rendering/svg/RenderSVGRoot.cpp (193728 => 193729)


--- branches/safari-601.4-branch/Source/WebCore/rendering/svg/RenderSVGRoot.cpp	2015-12-08 08:42:52 UTC (rev 193728)
+++ branches/safari-601.4-branch/Source/WebCore/rendering/svg/RenderSVGRoot.cpp	2015-12-08 08:44:09 UTC (rev 193729)
@@ -180,9 +180,10 @@
 
     if (!m_resourcesNeedingToInvalidateClients.isEmpty()) {
         // Invalidate resource clients, which may mark some nodes for layout.
-        HashSet<RenderSVGResourceContainer*>::iterator end = m_resourcesNeedingToInvalidateClients.end();
-        for (HashSet<RenderSVGResourceContainer*>::iterator it = m_resourcesNeedingToInvalidateClients.begin(); it != end; ++it)
-            (*it)->removeAllClientsFromCache();
+        for (auto& resource :  m_resourcesNeedingToInvalidateClients) {
+            resource->removeAllClientsFromCache();
+            SVGResourcesCache::clientStyleChanged(*resource, StyleDifferenceLayout, resource->style());
+        }
 
         m_isLayoutSizeChanged = false;
         SVGRenderSupport::layoutChildren(*this, false);

Modified: branches/safari-601.4-branch/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp (193728 => 193729)


--- branches/safari-601.4-branch/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp	2015-12-08 08:42:52 UTC (rev 193728)
+++ branches/safari-601.4-branch/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp	2015-12-08 08:44:09 UTC (rev 193729)
@@ -510,7 +510,7 @@
         // Dump final results that are used for rendering. No use in asking SVGPatternElement for its patternUnits(), as it may
         // link to other patterns using xlink:href, we need to build the full inheritance chain, aka. collectPatternProperties()
         PatternAttributes attributes;
-        pattern.patternElement().collectPatternAttributes(attributes);
+        pattern.collectPatternAttributes(attributes);
 
         writeNameValuePair(ts, "patternUnits", attributes.patternUnits());
         writeNameValuePair(ts, "patternContentUnits", attributes.patternContentUnits());

Modified: branches/safari-601.4-branch/Source/WebCore/svg/SVGPatternElement.cpp (193728 => 193729)


--- branches/safari-601.4-branch/Source/WebCore/svg/SVGPatternElement.cpp	2015-12-08 08:42:52 UTC (rev 193728)
+++ branches/safari-601.4-branch/Source/WebCore/svg/SVGPatternElement.cpp	2015-12-08 08:44:09 UTC (rev 193729)
@@ -187,65 +187,42 @@
     return createRenderer<RenderSVGResourcePattern>(*this, WTF::move(style));
 }
 
-static void setPatternAttributes(const SVGPatternElement& element, PatternAttributes& attributes)
+void SVGPatternElement::collectPatternAttributes(PatternAttributes& attributes) const
 {
-    if (!attributes.hasX() && element.hasAttribute(SVGNames::xAttr))
-        attributes.setX(element.x());
+    if (!attributes.hasX() && hasAttribute(SVGNames::xAttr))
+        attributes.setX(x());
 
-    if (!attributes.hasY() && element.hasAttribute(SVGNames::yAttr))
-        attributes.setY(element.y());
+    if (!attributes.hasY() && hasAttribute(SVGNames::yAttr))
+        attributes.setY(y());
 
-    if (!attributes.hasWidth() && element.hasAttribute(SVGNames::widthAttr))
-        attributes.setWidth(element.width());
+    if (!attributes.hasWidth() && hasAttribute(SVGNames::widthAttr))
+        attributes.setWidth(width());
 
-    if (!attributes.hasHeight() && element.hasAttribute(SVGNames::heightAttr))
-        attributes.setHeight(element.height());
+    if (!attributes.hasHeight() && hasAttribute(SVGNames::heightAttr))
+        attributes.setHeight(height());
 
-    if (!attributes.hasViewBox() && element.hasAttribute(SVGNames::viewBoxAttr) && element.viewBoxIsValid())
-        attributes.setViewBox(element.viewBox());
+    if (!attributes.hasViewBox() && hasAttribute(SVGNames::viewBoxAttr) && viewBoxIsValid())
+        attributes.setViewBox(viewBox());
 
-    if (!attributes.hasPreserveAspectRatio() && element.hasAttribute(SVGNames::preserveAspectRatioAttr))
-        attributes.setPreserveAspectRatio(element.preserveAspectRatio());
+    if (!attributes.hasPreserveAspectRatio() && hasAttribute(SVGNames::preserveAspectRatioAttr))
+        attributes.setPreserveAspectRatio(preserveAspectRatio());
 
-    if (!attributes.hasPatternUnits() && element.hasAttribute(SVGNames::patternUnitsAttr))
-        attributes.setPatternUnits(element.patternUnits());
+    if (!attributes.hasPatternUnits() && hasAttribute(SVGNames::patternUnitsAttr))
+        attributes.setPatternUnits(patternUnits());
 
-    if (!attributes.hasPatternContentUnits() && element.hasAttribute(SVGNames::patternContentUnitsAttr))
-        attributes.setPatternContentUnits(element.patternContentUnits());
+    if (!attributes.hasPatternContentUnits() && hasAttribute(SVGNames::patternContentUnitsAttr))
+        attributes.setPatternContentUnits(patternContentUnits());
 
-    if (!attributes.hasPatternTransform() && element.hasAttribute(SVGNames::patternTransformAttr)) {
+    if (!attributes.hasPatternTransform() && hasAttribute(SVGNames::patternTransformAttr)) {
         AffineTransform transform;
-        element.patternTransform().concatenate(transform);
+        patternTransform().concatenate(transform);
         attributes.setPatternTransform(transform);
     }
 
-    if (!attributes.hasPatternContentElement() && element.childElementCount())
-        attributes.setPatternContentElement(&element);
+    if (!attributes.hasPatternContentElement() && childElementCount())
+        attributes.setPatternContentElement(this);
 }
 
-void SVGPatternElement::collectPatternAttributes(PatternAttributes& attributes) const
-{
-    HashSet<const SVGPatternElement*> processedPatterns;
-    const SVGPatternElement* current = this;
-
-    while (true) {
-        setPatternAttributes(*current, attributes);
-        processedPatterns.add(current);
-
-        // Respect xlink:href, take attributes from referenced element
-        Element* refElement = SVGURIReference::targetElementFromIRIString(current->href(), document());
-        if (is<SVGPatternElement>(refElement)) {
-            current = downcast<SVGPatternElement>(refElement);
-
-            // Cycle detection
-            if (processedPatterns.contains(current))
-                return;
-        } else
-            return;
-    }
-    ASSERT_NOT_REACHED();
-}
-
 AffineTransform SVGPatternElement::localCoordinateSpaceTransform(SVGLocatable::CTMScope) const
 {
     AffineTransform matrix;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to