⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 285769 in webkit


Ignore:
Timestamp:
Nov 12, 2021, 6:12:05 PM (5 years ago)
Author:
Said Abou-Hallawa
Message:

REGRESSION(r285481): Infinite recursion with cyclic filter reference
https://bugs.webkit.org/show_bug.cgi?id=232972
rdar://85264240

Reviewed by Wenson Hsieh.

Source/WebCore:

Before r285481, we were creating the ImageBuffer of the referenced SVGElement
for the FEImage through RenderSVGResourceFilter::postApplyResource(). Now
we create this ImageBuffer through RenderSVGResourceFilter::applyResource().
The difference is at the end of RenderSVGResourceFilter::applyResource()
we add an entry to m_rendererFilterDataMap. This entry was preventing
trying to rebuild the SVGFilter for the same renderer if there is a
cyclic reference.

The fix is to add the entry in m_rendererFilterDataMap before creating the
SVGFilter. If an error happens, this entry will be removed before returning.

Test: svg/filters/feImage-cyclic-reference.svg

  • rendering/svg/RenderSVGResourceFilter.cpp:

(WebCore::RenderSVGResourceFilter::applyResource):

LayoutTests:

  • svg/filters/feImage-cyclic-reference-expected.txt: Added.
  • svg/filters/feImage-cyclic-reference.svg: Added.
Location:
trunk
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r285764 r285769  
     12021-11-12  Said Abou-Hallawa  <said@apple.com>
     2
     3        REGRESSION(r285481): Infinite recursion with cyclic filter reference
     4        https://bugs.webkit.org/show_bug.cgi?id=232972
     5        rdar://85264240
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        * svg/filters/feImage-cyclic-reference-expected.txt: Added.
     10        * svg/filters/feImage-cyclic-reference.svg: Added.
     11
    1122021-11-12  Rob Buis  <rbuis@igalia.com>
    213
  • trunk/Source/WebCore/ChangeLog

    r285764 r285769  
     12021-11-12  Said Abou-Hallawa  <said@apple.com>
     2
     3        REGRESSION(r285481): Infinite recursion with cyclic filter reference
     4        https://bugs.webkit.org/show_bug.cgi?id=232972
     5        rdar://85264240
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        Before r285481, we were creating the ImageBuffer of the referenced SVGElement
     10        for the FEImage through RenderSVGResourceFilter::postApplyResource(). Now
     11        we create this ImageBuffer through RenderSVGResourceFilter::applyResource().
     12        The difference is at the end of RenderSVGResourceFilter::applyResource()
     13        we add an entry to m_rendererFilterDataMap. This entry was preventing
     14        trying to rebuild the SVGFilter for the same renderer if there is a
     15        cyclic reference.
     16
     17        The fix is to add the entry in m_rendererFilterDataMap before creating the
     18        SVGFilter. If an error happens, this entry will be removed before returning.
     19
     20        Test: svg/filters/feImage-cyclic-reference.svg
     21
     22        * rendering/svg/RenderSVGResourceFilter.cpp:
     23        (WebCore::RenderSVGResourceFilter::applyResource):
     24
    1252021-11-12  Rob Buis  <rbuis@igalia.com>
    226
  • trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp

    r285618 r285769  
    9797    }
    9898
    99     auto filterData = makeUnique<FilterData>();
     99    auto addResult = m_rendererFilterDataMap.set(&renderer, makeUnique<FilterData>());
     100    auto filterData = addResult.iterator->value.get();
     101   
    100102    FloatRect targetBoundingBox = renderer.objectBoundingBox();
    101103
    102104    filterData->boundaries = SVGLengthContext::resolveRectangle<SVGFilterElement>(&filterElement(), filterElement().filterUnits(), targetBoundingBox);
    103     if (filterData->boundaries.isEmpty())
    104         return false;
     105    if (filterData->boundaries.isEmpty()) {
     106        m_rendererFilterDataMap.remove(&renderer);
     107        return false;
     108    }
    105109
    106110    // Determine absolute transformation matrix for filter.
    107111    AffineTransform absoluteTransform = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(renderer);
    108     if (!absoluteTransform.isInvertible())
    109         return false;
     112    if (!absoluteTransform.isInvertible()) {
     113        m_rendererFilterDataMap.remove(&renderer);
     114        return false;
     115    }
    110116
    111117    // Eliminate shear of the absolute transformation matrix, to be able to produce unsheared tile images for feTile.
     
    124130    filterData->builder = makeUnique<SVGFilterBuilder>();
    125131    filterData->filter = SVGFilter::create(filterElement(), *filterData->builder, filterScale, absoluteDrawingRegion, filterData->boundaries, targetBoundingBox);
    126     if (!filterData->filter)
    127         return false;
     132    if (!filterData->filter) {
     133        m_rendererFilterDataMap.remove(&renderer);
     134        return false;
     135    }
    128136
    129137    auto lastEffect = filterData->builder->lastEffect();
     
    145153    // Even if the target objectBoundingBox() is empty, we still have to draw the last effect result image in postApplyResource.
    146154    if (filterData->drawingRegion.isEmpty()) {
    147         ASSERT(!m_rendererFilterDataMap.contains(&renderer));
     155        ASSERT(m_rendererFilterDataMap.contains(&renderer));
    148156        filterData->savedContext = context;
    149         m_rendererFilterDataMap.set(&renderer, WTFMove(filterData));
    150157        return false;
    151158    }
     
    162169    auto sourceGraphic = SVGRenderingContext::createImageBuffer(filterData->drawingRegion, effectiveTransform, colorSpace, renderingMode, context);
    163170    if (!sourceGraphic) {
    164         ASSERT(!m_rendererFilterDataMap.contains(&renderer));
     171        ASSERT(m_rendererFilterDataMap.contains(&renderer));
    165172        filterData->savedContext = context;
    166         m_rendererFilterDataMap.set(&renderer, WTFMove(filterData));
    167173        return false;
    168174    }
     
    178184    context = &sourceGraphicContext;
    179185
    180     ASSERT(!m_rendererFilterDataMap.contains(&renderer));
    181     m_rendererFilterDataMap.set(&renderer, WTFMove(filterData));
    182 
     186    ASSERT(m_rendererFilterDataMap.contains(&renderer));
    183187    return true;
    184188}
Note: See TracChangeset for help on using the changeset viewer.