Title: [272931] trunk/Source/WebCore
Revision
272931
Author
za...@apple.com
Date
2021-02-16 14:55:52 -0800 (Tue, 16 Feb 2021)

Log Message

RenderElement::containingBlockForAbsolutePosition may call RenderObject::containingBlock recursively
https://bugs.webkit.org/show_bug.cgi?id=221976
<rdar://problem/72775667>

Reviewed by Simon Fraser.

When a RenderInline happens to be absolute positioned (this is a highly incorrect state, see webkit.org/b/221994), containingBlockForAbsolutePosition() calls containingBlock()
with |this| and in return containingBlock() calls back on containingBlockForAbsolutePosition() with the same renderer.
This patch ensures that we always call containingBlock() from containingBlockForAbsolutePosition() with an ancestor -mostly with the parent().

* rendering/RenderElement.cpp:
(WebCore::RenderElement::containingBlockForAbsolutePosition const):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (272930 => 272931)


--- trunk/Source/WebCore/ChangeLog	2021-02-16 22:47:58 UTC (rev 272930)
+++ trunk/Source/WebCore/ChangeLog	2021-02-16 22:55:52 UTC (rev 272931)
@@ -1,3 +1,18 @@
+2021-02-16  Zalan Bujtas  <za...@apple.com>
+
+        RenderElement::containingBlockForAbsolutePosition may call RenderObject::containingBlock recursively
+        https://bugs.webkit.org/show_bug.cgi?id=221976
+        <rdar://problem/72775667>
+
+        Reviewed by Simon Fraser.
+
+        When a RenderInline happens to be absolute positioned (this is a highly incorrect state, see webkit.org/b/221994), containingBlockForAbsolutePosition() calls containingBlock()
+        with |this| and in return containingBlock() calls back on containingBlockForAbsolutePosition() with the same renderer.
+        This patch ensures that we always call containingBlock() from containingBlockForAbsolutePosition() with an ancestor -mostly with the parent().
+
+        * rendering/RenderElement.cpp:
+        (WebCore::RenderElement::containingBlockForAbsolutePosition const):
+
 2021-02-16  Ryosuke Niwa  <rn...@webkit.org>
 
         EventHandler::updateSelectionForMouseDownDispatchingSelectStart should not use an orphaned selection

Modified: trunk/Source/WebCore/rendering/RenderElement.cpp (272930 => 272931)


--- trunk/Source/WebCore/rendering/RenderElement.cpp	2021-02-16 22:47:58 UTC (rev 272930)
+++ trunk/Source/WebCore/rendering/RenderElement.cpp	2021-02-16 22:55:52 UTC (rev 272931)
@@ -601,15 +601,22 @@
 
 RenderBlock* RenderElement::containingBlockForAbsolutePosition() const
 {
-    // A relatively positioned RenderInline forwards its absolute positioned descendants to
-    // its nearest non-anonymous containing block (to avoid having a positioned objects list in all RenderInlines).
-    auto* renderer = isRenderInline() ? const_cast<RenderElement*>(downcast<RenderElement>(this)) : parent();
-    while (renderer && !renderer->canContainAbsolutelyPositionedObjects())
-        renderer = renderer->parent();
+    auto nearestNonAnonymousContainingBlockIncludingSelf = [&] (auto* renderer) {
+        while (renderer && (!is<RenderBlock>(*renderer) || renderer->isAnonymousBlock()))
+            renderer = renderer->containingBlock();
+        return downcast<RenderBlock>(renderer);
+    };
+
+    if (is<RenderInline>(*this) && style().position() == PositionType::Relative) {
+        // A relatively positioned RenderInline forwards its absolute positioned descendants to
+        // its nearest non-anonymous containing block (to avoid having positioned objects list in RenderInlines).
+        return nearestNonAnonymousContainingBlockIncludingSelf(parent());
+    }
+    auto* ancestor = parent();
+    while (ancestor && !ancestor->canContainAbsolutelyPositionedObjects())
+        ancestor = ancestor->parent();
     // Make sure we only return non-anonymous RenderBlock as containing block.
-    while (renderer && (!is<RenderBlock>(*renderer) || renderer->isAnonymousBlock()))
-        renderer = renderer->containingBlock();
-    return downcast<RenderBlock>(renderer);
+    return nearestNonAnonymousContainingBlockIncludingSelf(ancestor);
 }
 
 static void addLayers(RenderElement& renderer, RenderLayer* parentLayer, RenderElement*& newObject, RenderLayer*& beforeChild)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to