2011-06-23 Jeffrey Pfau <jpfau@apple.com>
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 23 Jun 2011 10:44:01 +0000 (10:44 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 23 Jun 2011 10:44:01 +0000 (10:44 +0000)
        Reviewed by Nikolas Zimmermann.

        Incorrectly placed SVG gradients can cause crashes when referenced
        https://bugs.webkit.org/show_bug.cgi?id=62914

        Added tests to make sure fallback color is used properly with invalid gradients.

        * svg/custom/invalid-gradient-with-xlink-expected.png: Added.
        * svg/custom/invalid-gradient-with-xlink-expected.txt: Added.
        * svg/custom/invalid-gradient-with-xlink.svg: Added.
        * svg/custom/xlink-to-invalid-gradient-expected.png: Added.
        * svg/custom/xlink-to-invalid-gradient-expected.txt: Added.
        * svg/custom/xlink-to-invalid-gradient.svg: Added.
2011-06-23  Jeffrey Pfau  <jpfau@apple.com>

        Reviewed by Nikolas Zimmermann.

        Incorrectly placed SVG gradients can cause crashes when referenced
        https://bugs.webkit.org/show_bug.cgi?id=62914

        Added a check for gradient rendering contexts. If the contexts can't be found, the gradient must be in an invalid location, so we use the fallback color instead.

        Tests: svg/custom/invalid-gradient-with-xlink.svg
               svg/custom/xlink-to-invalid-gradient.svg

        * rendering/svg/RenderSVGResourceGradient.cpp:
        (WebCore::RenderSVGResourceGradient::applyResource):
        * rendering/svg/RenderSVGResourceGradient.h:
        * rendering/svg/RenderSVGResourceLinearGradient.cpp:
        (WebCore::RenderSVGResourceLinearGradient::collectGradientAttributes):
        * rendering/svg/RenderSVGResourceLinearGradient.h:
        * rendering/svg/RenderSVGResourceRadialGradient.cpp:
        (WebCore::RenderSVGResourceRadialGradient::collectGradientAttributes):
        * rendering/svg/RenderSVGResourceRadialGradient.h:
        * svg/SVGLinearGradientElement.cpp:
        (WebCore::SVGLinearGradientElement::collectGradientAttributes):
        * svg/SVGLinearGradientElement.h:
        * svg/SVGRadialGradientElement.cpp:
        (WebCore::SVGRadialGradientElement::collectGradientAttributes):
        * svg/SVGRadialGradientElement.h:

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

18 files changed:
LayoutTests/ChangeLog
LayoutTests/svg/custom/invalid-gradient-with-xlink-expected.png [new file with mode: 0644]
LayoutTests/svg/custom/invalid-gradient-with-xlink-expected.txt [new file with mode: 0644]
LayoutTests/svg/custom/invalid-gradient-with-xlink.svg [new file with mode: 0644]
LayoutTests/svg/custom/xlink-to-invalid-gradient-expected.png [new file with mode: 0644]
LayoutTests/svg/custom/xlink-to-invalid-gradient-expected.txt [new file with mode: 0644]
LayoutTests/svg/custom/xlink-to-invalid-gradient.svg [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp
Source/WebCore/rendering/svg/RenderSVGResourceGradient.h
Source/WebCore/rendering/svg/RenderSVGResourceLinearGradient.cpp
Source/WebCore/rendering/svg/RenderSVGResourceLinearGradient.h
Source/WebCore/rendering/svg/RenderSVGResourceRadialGradient.cpp
Source/WebCore/rendering/svg/RenderSVGResourceRadialGradient.h
Source/WebCore/svg/SVGLinearGradientElement.cpp
Source/WebCore/svg/SVGLinearGradientElement.h
Source/WebCore/svg/SVGRadialGradientElement.cpp
Source/WebCore/svg/SVGRadialGradientElement.h

index f43ff54..fbf0ddf 100644 (file)
@@ -1,3 +1,19 @@
+2011-06-23  Jeffrey Pfau  <jpfau@apple.com>
+
+        Reviewed by Nikolas Zimmermann.
+
+        Incorrectly placed SVG gradients can cause crashes when referenced
+        https://bugs.webkit.org/show_bug.cgi?id=62914
+
+        Added tests to make sure fallback color is used properly with invalid gradients.
+
+        * svg/custom/invalid-gradient-with-xlink-expected.png: Added.
+        * svg/custom/invalid-gradient-with-xlink-expected.txt: Added.
+        * svg/custom/invalid-gradient-with-xlink.svg: Added.
+        * svg/custom/xlink-to-invalid-gradient-expected.png: Added.
+        * svg/custom/xlink-to-invalid-gradient-expected.txt: Added.
+        * svg/custom/xlink-to-invalid-gradient.svg: Added.
+
 2011-06-23  Sergio Villar Senin  <svillar@igalia.com>
 
         Unreviewed, another bunch of GTK+ baselines for the new CSS2.1 tests added in r88913.
diff --git a/LayoutTests/svg/custom/invalid-gradient-with-xlink-expected.png b/LayoutTests/svg/custom/invalid-gradient-with-xlink-expected.png
new file mode 100644 (file)
index 0000000..38676c9
Binary files /dev/null and b/LayoutTests/svg/custom/invalid-gradient-with-xlink-expected.png differ
diff --git a/LayoutTests/svg/custom/invalid-gradient-with-xlink-expected.txt b/LayoutTests/svg/custom/invalid-gradient-with-xlink-expected.txt
new file mode 100644 (file)
index 0000000..7ef22e9
--- /dev/null
@@ -0,0 +1 @@
+PASS
diff --git a/LayoutTests/svg/custom/invalid-gradient-with-xlink.svg b/LayoutTests/svg/custom/invalid-gradient-with-xlink.svg
new file mode 100644 (file)
index 0000000..15fcab9
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+<svg\r
+   xmlns="http://www.w3.org/2000/svg"\r
+   xmlns:xlink="http://www.w3.org/1999/xlink"\r
+   version="1.0"\r
+   width="200"\r
+   height="200">\r
+<script><![CDATA[\r
+    if (window.layoutTestController)\r
+        layoutTestController.dumpAsText(true);\r
+]]></script>\r
+<defs>\r
+  <linearGradient id="linearGradient0">\r
+    <stop offset="0" stop-color="white"/>\r
+    <stop offset="1" stop-color="black"/>\r
+  </linearGradient>\r
+</defs>\r
+<rect width="200" height="200" style="fill:url(#linearGradient1) green;" id="rect0" />\r
+<text id="text0" x="10" y="20" style="fill:green">\r
+  PASS\r
+  <linearGradient id="linearGradient1" xlink:href="#linearGradient0" />\r
+</text>\r
+</svg>\r
diff --git a/LayoutTests/svg/custom/xlink-to-invalid-gradient-expected.png b/LayoutTests/svg/custom/xlink-to-invalid-gradient-expected.png
new file mode 100644 (file)
index 0000000..38676c9
Binary files /dev/null and b/LayoutTests/svg/custom/xlink-to-invalid-gradient-expected.png differ
diff --git a/LayoutTests/svg/custom/xlink-to-invalid-gradient-expected.txt b/LayoutTests/svg/custom/xlink-to-invalid-gradient-expected.txt
new file mode 100644 (file)
index 0000000..7ef22e9
--- /dev/null
@@ -0,0 +1 @@
+PASS
diff --git a/LayoutTests/svg/custom/xlink-to-invalid-gradient.svg b/LayoutTests/svg/custom/xlink-to-invalid-gradient.svg
new file mode 100644 (file)
index 0000000..96492c5
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+<svg\r
+   xmlns="http://www.w3.org/2000/svg"\r
+   xmlns:xlink="http://www.w3.org/1999/xlink"\r
+   version="1.0"\r
+   width="200"\r
+   height="200">\r
+<script><![CDATA[\r
+    if (window.layoutTestController)\r
+        layoutTestController.dumpAsText(true);\r
+]]></script>\r
+<defs>\r
+  <linearGradient id="linearGradient1" xlink:href="#linearGradient0" />\r
+</defs>\r
+<rect width="200" height="200" style="fill:url(#linearGradient1) green;" id="rect0" />\r
+<text id="text0" x="10" y="20" style="fill:green">\r
+  PASS\r
+  <linearGradient id="linearGradient0">\r
+    <stop offset="0" stop-color="white"/>\r
+    <stop offset="1" stop-color="black"/>\r
+  </linearGradient>\r
+</text>\r
+</svg>\r
index 52a32cc..27e25e2 100644 (file)
@@ -1,3 +1,31 @@
+2011-06-23  Jeffrey Pfau  <jpfau@apple.com>
+
+        Reviewed by Nikolas Zimmermann.
+
+        Incorrectly placed SVG gradients can cause crashes when referenced
+        https://bugs.webkit.org/show_bug.cgi?id=62914
+
+        Added a check for gradient rendering contexts. If the contexts can't be found, the gradient must be in an invalid location, so we use the fallback color instead.
+
+        Tests: svg/custom/invalid-gradient-with-xlink.svg
+               svg/custom/xlink-to-invalid-gradient.svg
+
+        * rendering/svg/RenderSVGResourceGradient.cpp:
+        (WebCore::RenderSVGResourceGradient::applyResource):
+        * rendering/svg/RenderSVGResourceGradient.h:
+        * rendering/svg/RenderSVGResourceLinearGradient.cpp:
+        (WebCore::RenderSVGResourceLinearGradient::collectGradientAttributes):
+        * rendering/svg/RenderSVGResourceLinearGradient.h:
+        * rendering/svg/RenderSVGResourceRadialGradient.cpp:
+        (WebCore::RenderSVGResourceRadialGradient::collectGradientAttributes):
+        * rendering/svg/RenderSVGResourceRadialGradient.h:
+        * svg/SVGLinearGradientElement.cpp:
+        (WebCore::SVGLinearGradientElement::collectGradientAttributes):
+        * svg/SVGLinearGradientElement.h:
+        * svg/SVGRadialGradientElement.cpp:
+        (WebCore::SVGRadialGradientElement::collectGradientAttributes):
+        * svg/SVGRadialGradientElement.h:
+
 2011-06-23  Dmitriy Vyukov  <dvyukov@google.com>
 
         Reviewed by David Levin.
index aa5cb4e..59e88bc 100644 (file)
@@ -155,7 +155,9 @@ bool RenderSVGResourceGradient::applyResource(RenderObject* object, RenderStyle*
 
     if (m_shouldCollectGradientAttributes) {
         gradientElement->updateAnimatedSVGAttribute(anyQName());
-        collectGradientAttributes(gradientElement);
+        if (!collectGradientAttributes(gradientElement))
+            return false;
+
         m_shouldCollectGradientAttributes = false;
     }
 
index c5635aa..6e8c1f8 100644 (file)
@@ -58,7 +58,7 @@ protected:
 
     virtual bool boundingBoxMode() const = 0;
     virtual void calculateGradientTransform(AffineTransform&) = 0;
-    virtual void collectGradientAttributes(SVGGradientElement*) = 0;
+    virtual bool collectGradientAttributes(SVGGradientElement*) = 0;
     virtual void buildGradient(GradientData*, SVGGradientElement*) const = 0;
 
     GradientSpreadMethod platformSpreadMethodFromSVGType(SVGGradientElement::SVGSpreadMethodType) const;
index 569a759..e58bdd9 100644 (file)
@@ -39,10 +39,10 @@ RenderSVGResourceLinearGradient::~RenderSVGResourceLinearGradient()
 {
 }
 
-void RenderSVGResourceLinearGradient::collectGradientAttributes(SVGGradientElement* gradientElement)
+bool RenderSVGResourceLinearGradient::collectGradientAttributes(SVGGradientElement* gradientElement)
 {
     m_attributes = LinearGradientAttributes();
-    static_cast<SVGLinearGradientElement*>(gradientElement)->collectGradientAttributes(m_attributes);
+    return static_cast<SVGLinearGradientElement*>(gradientElement)->collectGradientAttributes(m_attributes);
 }
 
 void RenderSVGResourceLinearGradient::buildGradient(GradientData* gradientData, SVGGradientElement* gradientElement) const
index 2d35418..8c9bb1d 100644 (file)
@@ -41,7 +41,7 @@ public:
 
     virtual bool boundingBoxMode() const { return m_attributes.boundingBoxMode(); }
     virtual void calculateGradientTransform(AffineTransform& transform) { transform = m_attributes.gradientTransform(); }
-    virtual void collectGradientAttributes(SVGGradientElement*);
+    virtual bool collectGradientAttributes(SVGGradientElement*);
     virtual void buildGradient(GradientData*, SVGGradientElement*) const;
 
 private:
index fd5861d..edd4293 100644 (file)
@@ -39,10 +39,10 @@ RenderSVGResourceRadialGradient::~RenderSVGResourceRadialGradient()
 {
 }
 
-void RenderSVGResourceRadialGradient::collectGradientAttributes(SVGGradientElement* gradientElement)
+bool RenderSVGResourceRadialGradient::collectGradientAttributes(SVGGradientElement* gradientElement)
 {
     m_attributes = RadialGradientAttributes();
-    static_cast<SVGRadialGradientElement*>(gradientElement)->collectGradientAttributes(m_attributes);
+    return static_cast<SVGRadialGradientElement*>(gradientElement)->collectGradientAttributes(m_attributes);
 }
 
 void RenderSVGResourceRadialGradient::buildGradient(GradientData* gradientData, SVGGradientElement* gradientElement) const
index 9d37d11..d30e4aa 100644 (file)
@@ -41,7 +41,7 @@ public:
 
     virtual bool boundingBoxMode() const { return m_attributes.boundingBoxMode(); }
     virtual void calculateGradientTransform(AffineTransform& transform) { transform = m_attributes.gradientTransform(); }
-    virtual void collectGradientAttributes(SVGGradientElement*);
+    virtual bool collectGradientAttributes(SVGGradientElement*);
     virtual void buildGradient(GradientData*, SVGGradientElement*) const;
 
 private:
index ae7bf39..6d7619d 100644 (file)
@@ -180,7 +180,7 @@ RenderObject* SVGLinearGradientElement::createRenderer(RenderArena* arena, Rende
     return new (arena) RenderSVGResourceLinearGradient(this);
 }
 
-void SVGLinearGradientElement::collectGradientAttributes(LinearGradientAttributes& attributes)
+bool SVGLinearGradientElement::collectGradientAttributes(LinearGradientAttributes& attributes)
 {
     HashSet<SVGGradientElement*> processedGradients;
 
@@ -188,6 +188,9 @@ void SVGLinearGradientElement::collectGradientAttributes(LinearGradientAttribute
     SVGGradientElement* current = this;
 
     while (current) {
+        if (!current->renderer())
+            return false;
+
         if (!attributes.hasSpreadMethod() && current->hasAttribute(SVGNames::spreadMethodAttr))
             attributes.setSpreadMethod(current->spreadMethod());
 
@@ -239,6 +242,8 @@ void SVGLinearGradientElement::collectGradientAttributes(LinearGradientAttribute
         } else
             current = 0;
     }
+
+    return true;
 }
 
 void SVGLinearGradientElement::calculateStartEndPoints(const LinearGradientAttributes& attributes, FloatPoint& startPoint, FloatPoint& endPoint)
index c9ef634..108360e 100644 (file)
@@ -33,7 +33,7 @@ class SVGLinearGradientElement : public SVGGradientElement {
 public:
     static PassRefPtr<SVGLinearGradientElement> create(const QualifiedName&, Document*);
 
-    void collectGradientAttributes(LinearGradientAttributes&);
+    bool collectGradientAttributes(LinearGradientAttributes&);
     void calculateStartEndPoints(const LinearGradientAttributes&, FloatPoint& startPoint, FloatPoint& endPoint);
 
 private:
index d2ecdc9..d75dcfc 100644 (file)
@@ -197,7 +197,7 @@ RenderObject* SVGRadialGradientElement::createRenderer(RenderArena* arena, Rende
     return new (arena) RenderSVGResourceRadialGradient(this);
 }
 
-void SVGRadialGradientElement::collectGradientAttributes(RadialGradientAttributes& attributes)
+bool SVGRadialGradientElement::collectGradientAttributes(RadialGradientAttributes& attributes)
 {
     HashSet<SVGGradientElement*> processedGradients;
 
@@ -205,6 +205,9 @@ void SVGRadialGradientElement::collectGradientAttributes(RadialGradientAttribute
     SVGGradientElement* current = this;
 
     while (current) {
+        if (!current->renderer())
+            return false;
+
         if (!attributes.hasSpreadMethod() && current->hasAttribute(SVGNames::spreadMethodAttr))
             attributes.setSpreadMethod(current->spreadMethod());
 
@@ -266,6 +269,8 @@ void SVGRadialGradientElement::collectGradientAttributes(RadialGradientAttribute
 
     if (!attributes.hasFy())
         attributes.setFy(attributes.cy());
+
+    return true;
 }
 
 void SVGRadialGradientElement::calculateFocalCenterPointsAndRadius(const RadialGradientAttributes& attributes, FloatPoint& focalPoint, FloatPoint& centerPoint, float& radius)
index 7c9c75d..e6d2f2b 100644 (file)
@@ -33,7 +33,7 @@ class SVGRadialGradientElement : public SVGGradientElement {
 public:
     static PassRefPtr<SVGRadialGradientElement> create(const QualifiedName&, Document*);
 
-    void collectGradientAttributes(RadialGradientAttributes&);
+    bool collectGradientAttributes(RadialGradientAttributes&);
     void calculateFocalCenterPointsAndRadius(const RadialGradientAttributes&, FloatPoint& focalPoint, FloatPoint& centerPoint, float& radius);
 
 private: