Title: [254559] trunk
Revision
254559
Author
[email protected]
Date
2020-01-14 22:32:01 -0800 (Tue, 14 Jan 2020)

Log Message

Long continuation chain could lead to stack exhaustion
https://bugs.webkit.org/show_bug.cgi?id=206271
<rdar://problem/41189798>

Reviewed by Simon Fraser.

Source/WebCore:

This patch replaces the recursive approach with an iterative one
to collect absolute quads across continuation.

Test: fast/inline/long-continuation-crash.html

* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::absoluteQuads const):
(WebCore::RenderBlock::absoluteQuadsIgnoringContinuation const):
* rendering/RenderBlock.h:
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::collectAbsoluteQuadsForContinuation const):
* rendering/RenderBoxModelObject.h:
(WebCore::RenderBoxModelObject::absoluteQuadsIgnoringContinuation const):
* rendering/RenderInline.cpp:
(WebCore::RenderInline::absoluteQuads const):
(WebCore::RenderInline::absoluteQuadsIgnoringContinuation const):
* rendering/RenderInline.h:

LayoutTests:

* fast/inline/long-continuation-crash.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (254558 => 254559)


--- trunk/LayoutTests/ChangeLog	2020-01-15 06:02:48 UTC (rev 254558)
+++ trunk/LayoutTests/ChangeLog	2020-01-15 06:32:01 UTC (rev 254559)
@@ -1,3 +1,13 @@
+2020-01-14  Zalan Bujtas  <[email protected]>
+
+        Long continuation chain could lead to stack exhaustion
+        https://bugs.webkit.org/show_bug.cgi?id=206271
+        <rdar://problem/41189798>
+
+        Reviewed by Simon Fraser.
+
+        * fast/inline/long-continuation-crash.html: Added.
+
 2020-01-14  Peng Liu  <[email protected]>
 
         [Media in GPU process] Implement the remote video layer support

Added: trunk/LayoutTests/fast/inline/long-continuation-crash-expected.txt (0 => 254559)


--- trunk/LayoutTests/fast/inline/long-continuation-crash-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/inline/long-continuation-crash-expected.txt	2020-01-15 06:32:01 UTC (rev 254559)
@@ -0,0 +1,1001 @@
+Pass in no crash x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+

Added: trunk/LayoutTests/fast/inline/long-continuation-crash.html (0 => 254559)


--- trunk/LayoutTests/fast/inline/long-continuation-crash.html	                        (rev 0)
+++ trunk/LayoutTests/fast/inline/long-continuation-crash.html	2020-01-15 06:32:01 UTC (rev 254559)
@@ -0,0 +1,20 @@
+<html>
+<title>This tests the selecting a long continuation content won't result in crash.</title>
+<body>Pass in no crash</body>
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+let spanContainer = document.createElement("span");
+document.body.appendChild(spanContainer);
+for (let i = 0; i < 1000; ++i) {
+    spanContainer.appendChild(document.createTextNode("x"));
+    spanContainer.appendChild(document.createElement("div"));
+}
+
+let range = new Range();
+range.setStartBefore(spanContainer);
+range.setEndAfter(spanContainer);
+const selection = window.getSelection();
+selection.addRange(range);
+</script>
+</html>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (254558 => 254559)


--- trunk/Source/WebCore/ChangeLog	2020-01-15 06:02:48 UTC (rev 254558)
+++ trunk/Source/WebCore/ChangeLog	2020-01-15 06:32:01 UTC (rev 254559)
@@ -1,3 +1,29 @@
+2020-01-14  Zalan Bujtas  <[email protected]>
+
+        Long continuation chain could lead to stack exhaustion
+        https://bugs.webkit.org/show_bug.cgi?id=206271
+        <rdar://problem/41189798>
+
+        Reviewed by Simon Fraser.
+
+        This patch replaces the recursive approach with an iterative one
+        to collect absolute quads across continuation.
+
+        Test: fast/inline/long-continuation-crash.html
+
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::absoluteQuads const):
+        (WebCore::RenderBlock::absoluteQuadsIgnoringContinuation const):
+        * rendering/RenderBlock.h:
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::collectAbsoluteQuadsForContinuation const):
+        * rendering/RenderBoxModelObject.h:
+        (WebCore::RenderBoxModelObject::absoluteQuadsIgnoringContinuation const):
+        * rendering/RenderInline.cpp:
+        (WebCore::RenderInline::absoluteQuads const):
+        (WebCore::RenderInline::absoluteQuadsIgnoringContinuation const):
+        * rendering/RenderInline.h:
+
 2020-01-14  Ryosuke Niwa  <[email protected]>
 
         Enable the offset assertion in HTMLTextFormControlElement::indexForPosition

Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (254558 => 254559)


--- trunk/Source/WebCore/rendering/RenderBlock.cpp	2020-01-15 06:02:48 UTC (rev 254558)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp	2020-01-15 06:32:01 UTC (rev 254559)
@@ -2781,21 +2781,24 @@
 
 void RenderBlock::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
 {
+    if (!continuation()) {
+        absoluteQuadsIgnoringContinuation({ { }, size() }, quads, wasFixed);
+        return;
+    }
     // For blocks inside inlines, we include margins so that we run right up to the inline boxes
     // above and below us (thus getting merged with them to form a single irregular shape).
-    auto* continuation = this->continuation();
-    FloatRect localRect = continuation
-        ? FloatRect(0, -collapsedMarginBefore(), width(), height() + collapsedMarginBefore() + collapsedMarginAfter())
-        : FloatRect(0, 0, width(), height());
-    
+    auto logicalRect = FloatRect { 0, -collapsedMarginBefore(), width(), height() + collapsedMarginBefore() + collapsedMarginAfter() };
+    absoluteQuadsIgnoringContinuation(logicalRect, quads, wasFixed);
+    collectAbsoluteQuadsForContinuation(quads, wasFixed);
+}
+
+void RenderBlock::absoluteQuadsIgnoringContinuation(const FloatRect& logicalRect, Vector<FloatQuad>& quads, bool* wasFixed) const
+{
     // FIXME: This is wrong for block-flows that are horizontal.
     // https://bugs.webkit.org/show_bug.cgi?id=46781
-    RenderFragmentedFlow* fragmentedFlow = enclosingFragmentedFlow();
-    if (!fragmentedFlow || !fragmentedFlow->absoluteQuadsForBox(quads, wasFixed, this, localRect.y(), localRect.maxY()))
-        quads.append(localToAbsoluteQuad(localRect, UseTransforms, wasFixed));
-
-    if (continuation)
-        continuation->absoluteQuads(quads, wasFixed);
+    auto* fragmentedFlow = enclosingFragmentedFlow();
+    if (!fragmentedFlow || !fragmentedFlow->absoluteQuadsForBox(quads, wasFixed, this, logicalRect.y(), logicalRect.maxY()))
+        quads.append(localToAbsoluteQuad(logicalRect, UseTransforms, wasFixed));
 }
 
 LayoutRect RenderBlock::rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const

Modified: trunk/Source/WebCore/rendering/RenderBlock.h (254558 => 254559)


--- trunk/Source/WebCore/rendering/RenderBlock.h	2020-01-15 06:02:48 UTC (rev 254558)
+++ trunk/Source/WebCore/rendering/RenderBlock.h	2020-01-15 06:32:01 UTC (rev 254559)
@@ -493,6 +493,8 @@
 
     void removePositionedObjectsIfNeeded(const RenderStyle& oldStyle, const RenderStyle& newStyle);
 
+    void absoluteQuadsIgnoringContinuation(const FloatRect&, Vector<FloatQuad>&, bool* wasFixed) const override;
+
 private:
     bool hasRareData() const;
     

Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp (254558 => 254559)


--- trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2020-01-15 06:02:48 UTC (rev 254558)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2020-01-15 06:32:01 UTC (rev 254559)
@@ -2695,4 +2695,21 @@
     return false;
 }
 
+void RenderBoxModelObject::collectAbsoluteQuadsForContinuation(Vector<FloatQuad>& quads, bool* wasFixed) const
+{
+    ASSERT(continuation());
+    for (auto* nextInContinuation = this->continuation(); nextInContinuation; nextInContinuation = nextInContinuation->continuation()) {
+        if (is<RenderBlock>(*nextInContinuation)) {
+            auto& blockBox = downcast<RenderBlock>(*nextInContinuation);
+            // For blocks inside inlines, we include margins so that we run right up to the inline boxes
+            // above and below us (thus getting merged with them to form a single irregular shape).
+            auto logicalRect = FloatRect { 0, -blockBox.collapsedMarginBefore(), blockBox.width(),
+                blockBox.height() + blockBox.collapsedMarginBefore() + blockBox.collapsedMarginAfter() };
+            nextInContinuation->absoluteQuadsIgnoringContinuation(logicalRect, quads, wasFixed);
+            continue;
+        }
+        nextInContinuation->absoluteQuadsIgnoringContinuation({ }, quads, wasFixed);
+    }
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.h (254558 => 254559)


--- trunk/Source/WebCore/rendering/RenderBoxModelObject.h	2020-01-15 06:02:48 UTC (rev 254558)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.h	2020-01-15 06:32:01 UTC (rev 254559)
@@ -294,6 +294,8 @@
 
 protected:
     LayoutUnit computedCSSPadding(const Length&) const;
+    virtual void absoluteQuadsIgnoringContinuation(const FloatRect&, Vector<FloatQuad>&, bool* /*wasFixed*/) const { ASSERT_NOT_REACHED(); }
+    void collectAbsoluteQuadsForContinuation(Vector<FloatQuad>& quads, bool* wasFixed) const;
 
 private:
     ContinuationChainNode& ensureContinuationChainNode();

Modified: trunk/Source/WebCore/rendering/RenderInline.cpp (254558 => 254559)


--- trunk/Source/WebCore/rendering/RenderInline.cpp	2020-01-15 06:02:48 UTC (rev 254558)
+++ trunk/Source/WebCore/rendering/RenderInline.cpp	2020-01-15 06:32:01 UTC (rev 254559)
@@ -412,11 +412,15 @@
 
 void RenderInline::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
 {
+    absoluteQuadsIgnoringContinuation({ }, quads, wasFixed);
+    if (continuation())
+        collectAbsoluteQuadsForContinuation(quads, wasFixed);
+}
+
+void RenderInline::absoluteQuadsIgnoringContinuation(const FloatRect&, Vector<FloatQuad>& quads, bool*) const
+{
     AbsoluteQuadsGeneratorContext context(this, quads);
     generateLineBoxRects(context);
-
-    if (RenderBoxModelObject* continuation = this->continuation())
-        continuation->absoluteQuads(quads, wasFixed);
 }
 
 #if PLATFORM(IOS_FAMILY)

Modified: trunk/Source/WebCore/rendering/RenderInline.h (254558 => 254559)


--- trunk/Source/WebCore/rendering/RenderInline.h	2020-01-15 06:02:48 UTC (rev 254558)
+++ trunk/Source/WebCore/rendering/RenderInline.h	2020-01-15 06:32:01 UTC (rev 254559)
@@ -109,6 +109,8 @@
     InlineBox* culledInlineFirstLineBox() const;
     InlineBox* culledInlineLastLineBox() const;
 
+    void absoluteQuadsIgnoringContinuation(const FloatRect&, Vector<FloatQuad>&, bool* wasFixed) const override;
+
     template<typename GeneratorContext>
     void generateLineBoxRects(GeneratorContext& yield) const;
     template<typename GeneratorContext>
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to