Changeset 286866 in webkit


Ignore:
Timestamp:
Dec 10, 2021 11:37:38 AM (3 years ago)
Author:
commit-queue@webkit.org
Message:

nullptr deref in ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatLeft>::updateOffsetIfNeeded
https://bugs.webkit.org/show_bug.cgi?id=234018

Patch by Gabriel Nava Marino <gnavamarino@apple.com> on 2021-12-10
Reviewed by Alan Bujtas.

Source/WebCore:

Test: fast/rendering/floating-object-renderer-crash.html

When destroying a given renderer, we first remove floats and out-of-flow positioned objects
from their containing block before detaching the renderer from the tree. We do this by obtaining
the renderer’s outermost block containing a floating object and recursively marking all siblings
and descendants for layout.

The criteria for continuing down the list of children require the current block to contain floats
or be able to shrink to avoid floats. However, we can have a scenario where the current child block
doesn’t have a float, but one of its descendants does. In this case, although we should continue to
that descendant and remove the float, we do not.

The proposal in this patch will instead check whether the child block contains a float, or any of its descendants do.
If so we should continue traversing towards that descendant.

  • rendering/RenderBlockFlow.cpp:

(WebCore::RenderBlockFlow::subtreeContainsFloat const):
(WebCore::RenderBlockFlow::subtreeContainsFloats const):
(WebCore::RenderBlockFlow::markAllDescendantsWithFloatsForLayout):

  • rendering/RenderBlockFlow.h:

LayoutTests:

  • fast/rendering/floating-object-renderer-crash-expected.txt: Added.
  • fast/rendering/floating-object-renderer-crash.html: Added.
Location:
trunk
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r286857 r286866  
     12021-12-10  Gabriel Nava Marino  <gnavamarino@apple.com>
     2
     3        nullptr deref in ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatLeft>::updateOffsetIfNeeded
     4        https://bugs.webkit.org/show_bug.cgi?id=234018
     5
     6        Reviewed by Alan Bujtas.
     7
     8        * fast/rendering/floating-object-renderer-crash-expected.txt: Added.
     9        * fast/rendering/floating-object-renderer-crash.html: Added.
     10
    1112021-12-10  Commit Queue  <commit-queue@webkit.org>
    212
  • trunk/Source/WebCore/ChangeLog

    r286864 r286866  
     12021-12-10  Gabriel Nava Marino  <gnavamarino@apple.com>
     2
     3        nullptr deref in ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatLeft>::updateOffsetIfNeeded
     4        https://bugs.webkit.org/show_bug.cgi?id=234018
     5
     6        Reviewed by Alan Bujtas.
     7
     8        Test: fast/rendering/floating-object-renderer-crash.html
     9
     10        When destroying a given renderer, we first remove floats and out-of-flow positioned objects
     11        from their containing block before detaching the renderer from the tree. We do this by obtaining
     12        the renderer’s outermost block containing a floating object and recursively marking all siblings
     13        and descendants for layout.
     14
     15        The criteria for continuing down the list of children require the current block to contain floats
     16        or be able to shrink to avoid floats. However, we can have a scenario where the current child block
     17        doesn’t have a float, but one of its descendants does. In this case, although we should continue to
     18        that descendant and remove the float, we do not.
     19
     20        The proposal in this patch will instead check whether the child block contains a float, or any of its descendants do.
     21        If so we should continue traversing towards that descendant.
     22
     23        * rendering/RenderBlockFlow.cpp:
     24        (WebCore::RenderBlockFlow::subtreeContainsFloat const):
     25        (WebCore::RenderBlockFlow::subtreeContainsFloats const):
     26        (WebCore::RenderBlockFlow::markAllDescendantsWithFloatsForLayout):
     27        * rendering/RenderBlockFlow.h:
     28
    1292021-12-10  Said Abou-Hallawa  <said@apple.com>
    230
  • trunk/Source/WebCore/rendering/RenderBlockFlow.cpp

    r286121 r286866  
    21102110}
    21112111
     2112bool RenderBlockFlow::subtreeContainsFloat(RenderBox& renderer) const
     2113{
     2114    bool contains = m_floatingObjects && m_floatingObjects->set().contains<FloatingObjectHashTranslator>(renderer);
     2115    for (auto& block : childrenOfType<RenderBlock>(*this)) {
     2116        if (!is<RenderBlockFlow>(block))
     2117            continue;
     2118        auto& blockFlow = downcast<RenderBlockFlow>(block);
     2119        contains |= blockFlow.subtreeContainsFloat(renderer);
     2120    }
     2121    return contains;
     2122}
     2123
     2124bool RenderBlockFlow::subtreeContainsFloats() const
     2125{
     2126    bool contains = m_floatingObjects && !m_floatingObjects->set().isEmpty();
     2127    for (auto& block : childrenOfType<RenderBlock>(*this)) {
     2128        if (!is<RenderBlockFlow>(block))
     2129            continue;
     2130        auto& blockFlow = downcast<RenderBlockFlow>(block);
     2131        contains |= blockFlow.subtreeContainsFloats();
     2132    }
     2133    return contains;
     2134}
     2135
    21122136void RenderBlockFlow::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
    21132137{
     
    28792903        }
    28802904        auto& blockFlow = downcast<RenderBlockFlow>(block);
    2881         if ((floatToRemove ? blockFlow.containsFloat(*floatToRemove) : blockFlow.containsFloats()) || blockFlow.shrinkToAvoidFloats())
     2905        if ((floatToRemove ? blockFlow.subtreeContainsFloat(*floatToRemove) : blockFlow.subtreeContainsFloats()) || blockFlow.shrinkToAvoidFloats())
    28822906            blockFlow.markAllDescendantsWithFloatsForLayout(floatToRemove, inLayout);
    28832907    }
  • trunk/Source/WebCore/rendering/RenderBlockFlow.h

    r285615 r286866  
    279279    bool containsFloats() const override { return m_floatingObjects && !m_floatingObjects->set().isEmpty(); }
    280280    bool containsFloat(RenderBox&) const;
     281    bool subtreeContainsFloats() const;
     282    bool subtreeContainsFloat(RenderBox&) const;
    281283
    282284    void deleteLines() override;
Note: See TracChangeset for help on using the changeset viewer.