Changeset 174137 in webkit


Ignore:
Timestamp:
Sep 30, 2014 5:14:03 PM (9 years ago)
Author:
commit-queue@webkit.org
Message:

Source/WebCore:
Stack overflow with enormous SVG filter
https://bugs.webkit.org/show_bug.cgi?id=63290

Prevent building an SVG filter if it has more than 200 FilterEffect nodes in its map
regardless whether they will be connected to its lastEffect or not. Also discard any
filter which has more 100 contributing FilterEffect nodes in its tree.

Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2014-09-30
Reviewed by Dean Jackson.

Tests: svg/filters/svg-deeply-nested-crash.html

  • platform/graphics/filters/FilterEffect.cpp:

(WebCore::collectEffects):
(WebCore::FilterEffect::totalNumberOfEffectInputs):

  • platform/graphics/filters/FilterEffect.h:

-- Add a method to return the total number of input FilterEffect's contributing to a FilterEffect.

  • rendering/svg/RenderSVGResourceFilter.cpp:

(WebCore::RenderSVGResourceFilter::buildPrimitives):
-- Do not build a filter if it has more than 200 FilterEffects in its map.
(WebCore::RenderSVGResourceFilter::applyResource):
-- Discard a filter after it was built if it has more than 100 FilterEffects in its tree.

LayoutTests:
Stack overflow with enormous SVG filter.
https://bugs.webkit.org/show_bug.cgi?id=63290.

Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2014-09-30
Reviewed by Dean Jackson.

Test if an SVG filter with deeply nested tree of FilterEffects can be loaded
with no crash. Make sure other valid filters can still be referenced by SVG
drawing elements. An SVG Filter will be ignored if the number of effects in
its map is greater than 200 or the total number of effects connected to its
last effect is greater than 100.

  • svg/filters/svg-deeply-nested-crash-expected.txt: Added.
  • svg/filters/svg-deeply-nested-crash.html: Added.
Location:
trunk
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r174135 r174137  
     12014-09-30  Said Abou-Hallawa  <sabouhallawa@apple.com>
     2
     3        Stack overflow with enormous SVG filter.
     4        https://bugs.webkit.org/show_bug.cgi?id=63290.
     5
     6        Reviewed by Dean Jackson.
     7
     8        Test if an SVG filter with deeply nested tree of FilterEffects can be loaded
     9        with no crash. Make sure other valid filters can still be referenced by SVG
     10        drawing elements. An SVG Filter will be ignored if the number of effects in
     11        its map is greater than 200 or the total number of effects connected to its
     12        last effect is greater than 100.
     13
     14        * svg/filters/svg-deeply-nested-crash-expected.txt: Added.
     15        * svg/filters/svg-deeply-nested-crash.html: Added.
     16
    1172014-09-30  Roger Fong  <roger_fong@apple.com>
    218
  • trunk/Source/WebCore/ChangeLog

    r174132 r174137  
     12014-09-30  Said Abou-Hallawa  <sabouhallawa@apple.com>
     2
     3        Stack overflow with enormous SVG filter
     4        https://bugs.webkit.org/show_bug.cgi?id=63290
     5
     6        Prevent building an SVG filter if it has more than 200 FilterEffect nodes in its map
     7        regardless whether they will be connected to its lastEffect or not. Also discard any
     8        filter which has more 100 contributing FilterEffect nodes in its tree.
     9
     10        Reviewed by Dean Jackson.
     11
     12        Tests: svg/filters/svg-deeply-nested-crash.html
     13
     14        * platform/graphics/filters/FilterEffect.cpp:
     15        (WebCore::collectEffects):
     16        (WebCore::FilterEffect::totalNumberOfEffectInputs):
     17        * platform/graphics/filters/FilterEffect.h:
     18        -- Add a method to return the total number of input FilterEffect's contributing to a FilterEffect.
     19        * rendering/svg/RenderSVGResourceFilter.cpp:
     20        (WebCore::RenderSVGResourceFilter::buildPrimitives):
     21        -- Do not build a filter if it has more than 200 FilterEffects in its map.
     22        (WebCore::RenderSVGResourceFilter::applyResource):
     23        -- Discard a filter after it was built if it has more than 100 FilterEffects in its tree.
     24
    1252014-09-30  Christophe Dumez  <cdumez@apple.com>
    226
  • trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp

    r173397 r174137  
    103103    ASSERT_WITH_SECURITY_IMPLICATION(number < m_inputEffects.size());
    104104    return m_inputEffects.at(number).get();
     105}
     106
     107static unsigned collectEffects(const FilterEffect*effect, HashSet<const FilterEffect*>& allEffects)
     108{
     109    allEffects.add(effect);
     110    unsigned size = effect->numberOfEffectInputs();
     111    for (unsigned i = 0; i < size; ++i) {
     112        FilterEffect* in = effect->inputEffect(i);
     113        collectEffects(in, allEffects);
     114    }
     115    return allEffects.size();
     116}
     117
     118unsigned FilterEffect::totalNumberOfEffectInputs() const
     119{
     120    HashSet<const FilterEffect*> allEffects;
     121    return collectEffects(this, allEffects);
    105122}
    106123
  • trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h

    r173397 r174137  
    2929#include <runtime/Uint8ClampedArray.h>
    3030
     31#include <wtf/HashSet.h>
    3132#include <wtf/RefCounted.h>
    3233#include <wtf/RefPtr.h>
     
    7980    FilterEffect* inputEffect(unsigned) const;
    8081    unsigned numberOfEffectInputs() const { return m_inputEffects.size(); }
     82    unsigned totalNumberOfEffectInputs() const;
    8183   
    8284    inline bool hasResult() const
  • trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp

    r173397 r174137  
    7777std::unique_ptr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives(SVGFilter* filter) const
    7878{
     79    static const unsigned maxCountChildNodes = 200;
     80    if (filterElement().countChildNodes() > maxCountChildNodes)
     81        return nullptr;
     82
    7983    FloatRect targetBoundingBox = filter->targetBoundingBox();
    8084
     
    173177    filterData->filter->setFilterResolution(scale);
    174178
     179    static const unsigned maxTotalOfEffectInputs = 100;
    175180    FilterEffect* lastEffect = filterData->builder->lastEffect();
    176     if (!lastEffect)
     181    if (!lastEffect || lastEffect->totalNumberOfEffectInputs() > maxTotalOfEffectInputs)
    177182        return false;
    178183
Note: See TracChangeset for help on using the changeset viewer.