2011-05-06 Cris Neckar <cdn@chromium.org>
authorcdn@chromium.org <cdn@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 6 May 2011 07:33:18 +0000 (07:33 +0000)
committercdn@chromium.org <cdn@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 6 May 2011 07:33:18 +0000 (07:33 +0000)
        Reviewed by Dirk Schulze.

        Change maxEffectRect to a FloatRect.
        https://bugs.webkit.org/show_bug.cgi?id=59551

        * svg/filters/filter-after-transform-crash-expected.txt: Added.
        * svg/filters/filter-after-transform-crash.svg: Added.
2011-05-06  Cris Neckar  <cdn@chromium.org>

        Reviewed by Dirk Schulze.

        Tests for crash when a transform is applied to certain filters.
        https://bugs.webkit.org/show_bug.cgi?id=59551

        Test: svg/filters/filter-after-transform-crash.svg

        * platform/graphics/filters/FEComposite.cpp:
        (WebCore::FEComposite::determineAbsolutePaintRect):
        * platform/graphics/filters/FEConvolveMatrix.h:
        (WebCore::FEConvolveMatrix::determineAbsolutePaintRect):
        * platform/graphics/filters/FEDisplacementMap.h:
        (WebCore::FEDisplacementMap::determineAbsolutePaintRect):
        * platform/graphics/filters/FEFlood.h:
        (WebCore::FEFlood::determineAbsolutePaintRect):
        * platform/graphics/filters/FELighting.h:
        (WebCore::FELighting::determineAbsolutePaintRect):
        * platform/graphics/filters/FETile.h:
        (WebCore::FETile::determineAbsolutePaintRect):
        * platform/graphics/filters/FETurbulence.h:
        (WebCore::FETurbulence::determineAbsolutePaintRect):
        * platform/graphics/filters/FilterEffect.cpp:
        (WebCore::isFilterSizeValid):
        (WebCore::FilterEffect::determineAbsolutePaintRect):
        (WebCore::FilterEffect::asUnmultipliedImage):
        (WebCore::FilterEffect::asPremultipliedImage):
        (WebCore::FilterEffect::copyUnmultipliedImage):
        (WebCore::FilterEffect::copyPremultipliedImage):
        (WebCore::FilterEffect::createUnmultipliedImageResult):
        (WebCore::FilterEffect::createPremultipliedImageResult):
        * platform/graphics/filters/FilterEffect.h:
        (WebCore::FilterEffect::maxEffectRect):
        (WebCore::FilterEffect::setMaxEffectRect):
        * rendering/svg/RenderSVGResourceFilter.cpp:
        * rendering/svg/RenderSVGResourceFilterPrimitive.cpp:
        (WebCore::RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion):

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

15 files changed:
LayoutTests/ChangeLog
LayoutTests/svg/filters/filter-after-transform-crash-expected.txt [new file with mode: 0644]
LayoutTests/svg/filters/filter-after-transform-crash.svg [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/filters/FEComposite.cpp
Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h
Source/WebCore/platform/graphics/filters/FEDisplacementMap.h
Source/WebCore/platform/graphics/filters/FEFlood.h
Source/WebCore/platform/graphics/filters/FELighting.h
Source/WebCore/platform/graphics/filters/FETile.h
Source/WebCore/platform/graphics/filters/FETurbulence.h
Source/WebCore/platform/graphics/filters/FilterEffect.cpp
Source/WebCore/platform/graphics/filters/FilterEffect.h
Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp

index 150d398..db86470 100644 (file)
@@ -1,3 +1,13 @@
+2011-05-06  Cris Neckar  <cdn@chromium.org>
+
+        Reviewed by Dirk Schulze.
+
+        Change maxEffectRect to a FloatRect.
+        https://bugs.webkit.org/show_bug.cgi?id=59551
+
+        * svg/filters/filter-after-transform-crash-expected.txt: Added.
+        * svg/filters/filter-after-transform-crash.svg: Added.
+
 2011-05-04  Philippe Normand  <pnormand@igalia.com>
 
         Reviewed by Dimitri Glazkov.
diff --git a/LayoutTests/svg/filters/filter-after-transform-crash-expected.txt b/LayoutTests/svg/filters/filter-after-transform-crash-expected.txt
new file mode 100644 (file)
index 0000000..e269480
--- /dev/null
@@ -0,0 +1 @@
+PASS - Applying filter does not crash.
diff --git a/LayoutTests/svg/filters/filter-after-transform-crash.svg b/LayoutTests/svg/filters/filter-after-transform-crash.svg
new file mode 100644 (file)
index 0000000..654c8b7
--- /dev/null
@@ -0,0 +1,22 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="80" y="80" width="300" height="180" viewBox="0 0 200 120">
+    <script>
+    if (window.layoutTestController)
+        layoutTestController.dumpAsText();
+    </script>
+    <defs>
+        <filter id="MyFilter" filterUnits="userSpaceOnUse" >
+            <feGaussianBlur />
+            <feOffset />
+            <feSpecularLighting >
+                <fePointLight />
+            </feSpecularLighting>
+            <feComposite />
+            <feMerge>
+                <feMergeNode />
+                <feMergeNode />
+            </feMerge>
+        </filter>
+    </defs>
+    <g transform="matrix(0,-256152301,1000,0,1,1) " filter="url(#MyFilter)" />
+    <text>PASS - Applying filter does not crash.</text>
+</svg>
\ No newline at end of file
index 0264913..121cfe8 100644 (file)
@@ -1,3 +1,42 @@
+2011-05-06  Cris Neckar  <cdn@chromium.org>
+
+        Reviewed by Dirk Schulze.
+
+        Tests for crash when a transform is applied to certain filters.
+        https://bugs.webkit.org/show_bug.cgi?id=59551
+
+        Test: svg/filters/filter-after-transform-crash.svg
+
+        * platform/graphics/filters/FEComposite.cpp:
+        (WebCore::FEComposite::determineAbsolutePaintRect):
+        * platform/graphics/filters/FEConvolveMatrix.h:
+        (WebCore::FEConvolveMatrix::determineAbsolutePaintRect):
+        * platform/graphics/filters/FEDisplacementMap.h:
+        (WebCore::FEDisplacementMap::determineAbsolutePaintRect):
+        * platform/graphics/filters/FEFlood.h:
+        (WebCore::FEFlood::determineAbsolutePaintRect):
+        * platform/graphics/filters/FELighting.h:
+        (WebCore::FELighting::determineAbsolutePaintRect):
+        * platform/graphics/filters/FETile.h:
+        (WebCore::FETile::determineAbsolutePaintRect):
+        * platform/graphics/filters/FETurbulence.h:
+        (WebCore::FETurbulence::determineAbsolutePaintRect):
+        * platform/graphics/filters/FilterEffect.cpp:
+        (WebCore::isFilterSizeValid):
+        (WebCore::FilterEffect::determineAbsolutePaintRect):
+        (WebCore::FilterEffect::asUnmultipliedImage):
+        (WebCore::FilterEffect::asPremultipliedImage):
+        (WebCore::FilterEffect::copyUnmultipliedImage):
+        (WebCore::FilterEffect::copyPremultipliedImage):
+        (WebCore::FilterEffect::createUnmultipliedImageResult):
+        (WebCore::FilterEffect::createPremultipliedImageResult):
+        * platform/graphics/filters/FilterEffect.h:
+        (WebCore::FilterEffect::maxEffectRect):
+        (WebCore::FilterEffect::setMaxEffectRect):
+        * rendering/svg/RenderSVGResourceFilter.cpp:
+        * rendering/svg/RenderSVGResourceFilterPrimitive.cpp:
+        (WebCore::RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion):
+
 2011-05-06  Luke Macpherson   <macpherson@chromium.org>
 
         Reviewed by Eric Seidel.
index d73498e..d190e8f 100644 (file)
@@ -187,7 +187,7 @@ void FEComposite::determineAbsolutePaintRect()
     case FECOMPOSITE_OPERATOR_ARITHMETIC:
         // Arithmetic may influnce the compele filter primitive region. So we can't
         // optimize the paint region here.
-        setAbsolutePaintRect(maxEffectRect());
+        setAbsolutePaintRect(enclosingIntRect(maxEffectRect()));
         return;
     default:
         // Take the union of both input effects.
index 5dc8873..940aa92 100644 (file)
@@ -75,7 +75,7 @@ public:
     virtual void apply();
     virtual void dump();
 
-    virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(maxEffectRect()); }
+    virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(enclosingIntRect(maxEffectRect())); }
 
     virtual TextStream& externalRepresentation(TextStream&, int indention) const;
 
index 9b7dda8..fd80458 100644 (file)
@@ -53,7 +53,7 @@ public:
     virtual void apply();
     virtual void dump();
 
-    virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(maxEffectRect()); }
+    virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(enclosingIntRect(maxEffectRect())); }
 
     virtual TextStream& externalRepresentation(TextStream&, int indention) const;
 
index cac4153..497ca24 100644 (file)
@@ -42,7 +42,7 @@ public:
     virtual void apply();
     virtual void dump();
 
-    virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(maxEffectRect()); }
+    virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(enclosingIntRect(maxEffectRect())); }
 
     virtual TextStream& externalRepresentation(TextStream&, int indention) const;
 
index b908ecf..b82144a 100644 (file)
@@ -45,7 +45,7 @@ class FELighting : public FilterEffect {
 public:
     virtual void apply();
 
-    virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(maxEffectRect()); }
+    virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(enclosingIntRect(maxEffectRect())); }
 
 protected:
     enum LightingType {
index 9b02b4c..72e7e60 100644 (file)
@@ -35,7 +35,7 @@ public:
     virtual void apply();
     virtual void dump();
 
-    virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(maxEffectRect()); }
+    virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(enclosingIntRect(maxEffectRect())); }
 
     virtual FilterEffectType filterEffectType() const { return FilterEffectTypeTile; }
 
index 04662bf..a71f76a 100644 (file)
@@ -65,7 +65,7 @@ public:
     virtual void apply();
     virtual void dump();
     
-    virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(maxEffectRect()); }
+    virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(enclosingIntRect(maxEffectRect())); }
 
     virtual TextStream& externalRepresentation(TextStream&, int indention) const;
 
index c0e6e4a..6e5422e 100644 (file)
@@ -46,6 +46,14 @@ FilterEffect::~FilterEffect()
 {
 }
 
+inline bool isFilterSizeValid(IntRect rect)
+{
+    if (rect.width() < 0 || rect.width() > kMaxFilterSize
+        || rect.height() < 0 || rect.height() > kMaxFilterSize)
+        return false;
+    return true;
+}
+
 void FilterEffect::determineAbsolutePaintRect()
 {
     m_absolutePaintRect = IntRect();
@@ -54,7 +62,7 @@ void FilterEffect::determineAbsolutePaintRect()
         m_absolutePaintRect.unite(m_inputEffects.at(i)->absolutePaintRect());
     
     // SVG specification wants us to clip to primitive subregion.
-    m_absolutePaintRect.intersect(m_maxEffectRect);
+    m_absolutePaintRect.intersect(enclosingIntRect(m_maxEffectRect));
 }
 
 IntRect FilterEffect::requestedRegionOfInputImageData(const IntRect& effectRect) const
@@ -104,6 +112,7 @@ ImageBuffer* FilterEffect::asImageBuffer()
 
 PassRefPtr<ByteArray> FilterEffect::asUnmultipliedImage(const IntRect& rect)
 {
+    ASSERT(isFilterSizeValid(rect));
     RefPtr<ByteArray> imageData = ByteArray::create(rect.width() * rect.height() * 4);
     copyUnmultipliedImage(imageData.get(), rect);
     return imageData.release();
@@ -111,6 +120,7 @@ PassRefPtr<ByteArray> FilterEffect::asUnmultipliedImage(const IntRect& rect)
 
 PassRefPtr<ByteArray> FilterEffect::asPremultipliedImage(const IntRect& rect)
 {
+    ASSERT(isFilterSizeValid(rect));
     RefPtr<ByteArray> imageData = ByteArray::create(rect.width() * rect.height() * 4);
     copyPremultipliedImage(imageData.get(), rect);
     return imageData.release();
@@ -169,6 +179,7 @@ void FilterEffect::copyUnmultipliedImage(ByteArray* destination, const IntRect&
         if (m_imageBufferResult)
             m_unmultipliedImageResult = m_imageBufferResult->getUnmultipliedImageData(IntRect(IntPoint(), m_absolutePaintRect.size()));
         else {
+            ASSERT(isFilterSizeValid(m_absolutePaintRect));
             m_unmultipliedImageResult = ByteArray::create(m_absolutePaintRect.width() * m_absolutePaintRect.height() * 4);
             unsigned char* sourceComponent = m_premultipliedImageResult->data();
             unsigned char* destinationComponent = m_unmultipliedImageResult->data();
@@ -202,6 +213,7 @@ void FilterEffect::copyPremultipliedImage(ByteArray* destination, const IntRect&
         if (m_imageBufferResult)
             m_premultipliedImageResult = m_imageBufferResult->getPremultipliedImageData(IntRect(IntPoint(), m_absolutePaintRect.size()));
         else {
+            ASSERT(isFilterSizeValid(m_absolutePaintRect));
             m_premultipliedImageResult = ByteArray::create(m_absolutePaintRect.width() * m_absolutePaintRect.height() * 4);
             unsigned char* sourceComponent = m_unmultipliedImageResult->data();
             unsigned char* destinationComponent = m_premultipliedImageResult->data();
@@ -238,6 +250,8 @@ ByteArray* FilterEffect::createUnmultipliedImageResult()
 {
     // Only one result type is allowed.
     ASSERT(!hasResult());
+    ASSERT(isFilterSizeValid(m_absolutePaintRect));
+
     determineAbsolutePaintRect();
     if (m_absolutePaintRect.isEmpty())
         return 0;
@@ -249,6 +263,8 @@ ByteArray* FilterEffect::createPremultipliedImageResult()
 {
     // Only one result type is allowed.
     ASSERT(!hasResult());
+    ASSERT(isFilterSizeValid(m_absolutePaintRect));
+
     determineAbsolutePaintRect();
     if (m_absolutePaintRect.isEmpty())
         return 0;
index 2de8ac5..74fdc29 100644 (file)
@@ -32,6 +32,8 @@
 #include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
 
+static const float kMaxFilterSize = 5000.0f;
+
 namespace WebCore {
 
 class Filter;
@@ -74,8 +76,8 @@ public:
     IntRect absolutePaintRect() const { return m_absolutePaintRect; }
     void setAbsolutePaintRect(const IntRect& absolutePaintRect) { m_absolutePaintRect = absolutePaintRect; }
 
-    IntRect maxEffectRect() const { return m_maxEffectRect; }
-    void setMaxEffectRect(const IntRect& maxEffectRect) { m_maxEffectRect = maxEffectRect; } 
+    FloatRect maxEffectRect() const { return m_maxEffectRect; }
+    void setMaxEffectRect(const FloatRect& maxEffectRect) { m_maxEffectRect = maxEffectRect; } 
 
     virtual void apply() = 0;
     virtual void dump() = 0;
@@ -128,7 +130,7 @@ private:
     
     // The maximum size of a filter primitive. In SVG this is the primitive subregion in absolute coordinate space.
     // The absolute paint rect should never be bigger than m_maxEffectRect.
-    IntRect m_maxEffectRect;
+    FloatRect m_maxEffectRect;
     Filter* m_filter;
 
 private:
index 3b848d9..4a02b17 100644 (file)
@@ -27,6 +27,7 @@
 #include "RenderSVGResourceFilter.h"
 
 #include "AffineTransform.h"
+#include "FilterEffect.h"
 #include "FloatPoint.h"
 #include "FloatRect.h"
 #include "GraphicsContext.h"
@@ -48,8 +49,6 @@
 #include <wtf/UnusedParam.h>
 #include <wtf/Vector.h>
 
-static const float kMaxFilterSize = 5000.0f;
-
 using namespace std;
 
 namespace WebCore {
index f077bfd..b74122e 100644 (file)
@@ -128,7 +128,7 @@ FloatRect RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(Fi
     absoluteScaledFilterRegion.scale(filterResolution.width(), filterResolution.height());
     absoluteSubregion.intersect(absoluteScaledFilterRegion);
 
-    effect->setMaxEffectRect(enclosingIntRect(absoluteSubregion));
+    effect->setMaxEffectRect(absoluteSubregion);
     return subregion;
 }