Title: [275067] trunk
Revision
275067
Author
[email protected]
Date
2021-03-25 17:09:23 -0700 (Thu, 25 Mar 2021)

Log Message

Source/WebCore:
[RenderTreeBuilder] Do not try to normalize the tree while destroying the multicolumn flow
https://bugs.webkit.org/show_bug.cgi?id=223722
<rdar://75731256>

Reviewed by Simon Fraser.

Test: fast/multicol/crash-while-destroying-the-column-context.html

This patch ensures that we don't start moving around parts of the fragmented flow subtree (e.g. collapsing anonymous blocks) while
trying place the spanner renderers back to their original positions as part of the "we don't need multicolumn context anymore".
(e.g spanner placeholder is removed -> triggers anon block collapsing -> moves subtrees around inside the multicolumn subtree -> insertion happens -> spanner placeholder gets re-validated)

* rendering/updating/RenderTreeBuilder.cpp:
(WebCore::RenderTreeBuilder::destroy):
* rendering/updating/RenderTreeBuilder.h:
* rendering/updating/RenderTreeBuilderBlock.cpp:
(WebCore::RenderTreeBuilder::Block::detach):
* rendering/updating/RenderTreeBuilderMultiColumn.cpp:
(WebCore::RenderTreeBuilder::MultiColumn::destroyFragmentedFlow):
(WebCore::RenderTreeBuilder::MultiColumn::handleSpannerRemoval):
(WebCore::RenderTreeBuilder::MultiColumn::multiColumnRelativeWillBeRemoved):
* rendering/updating/RenderTreeBuilderMultiColumn.h:

LayoutTests:
[RenederTreeBuilder] Do not try to normalize the tree while destroying the multicolumn flow
https://bugs.webkit.org/show_bug.cgi?id=223722
<rdar://75731256>

Reviewed by Simon Fraser.

* fast/multicol/crash-while-destroying-the-column-context-expected.txt: Added.
* fast/multicol/crash-while-destroying-the-column-context.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (275066 => 275067)


--- trunk/LayoutTests/ChangeLog	2021-03-25 23:35:20 UTC (rev 275066)
+++ trunk/LayoutTests/ChangeLog	2021-03-26 00:09:23 UTC (rev 275067)
@@ -1,3 +1,14 @@
+2021-03-25  Zalan Bujtas  <[email protected]>
+
+        [RenederTreeBuilder] Do not try to normalize the tree while destroying the multicolumn flow
+        https://bugs.webkit.org/show_bug.cgi?id=223722
+        <rdar://75731256>
+
+        Reviewed by Simon Fraser.
+
+        * fast/multicol/crash-while-destroying-the-column-context-expected.txt: Added.
+        * fast/multicol/crash-while-destroying-the-column-context.html: Added.
+
 2021-03-25  Andres Gonzalez  <[email protected]>
 
         AX: Consider implementing @aria-details.

Added: trunk/LayoutTests/fast/multicol/crash-while-destroying-the-column-context-expected.txt (0 => 275067)


--- trunk/LayoutTests/fast/multicol/crash-while-destroying-the-column-context-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/multicol/crash-while-destroying-the-column-context-expected.txt	2021-03-26 00:09:23 UTC (rev 275067)
@@ -0,0 +1 @@
+

Added: trunk/LayoutTests/fast/multicol/crash-while-destroying-the-column-context.html (0 => 275067)


--- trunk/LayoutTests/fast/multicol/crash-while-destroying-the-column-context.html	                        (rev 0)
+++ trunk/LayoutTests/fast/multicol/crash-while-destroying-the-column-context.html	2021-03-26 00:09:23 UTC (rev 275067)
@@ -0,0 +1,28 @@
+<style>
+  body {
+    writing-mode: vertical-rl;
+    block-size: 0;
+  }
+  div {
+    column-span: all;
+  }
+  :nth-child(2) {
+    float: left;
+  }
+  :read-only {
+    overflow-y: -webkit-paged-y;
+  }
+</style>
+<script>
+  if (window.testRunner)
+    testRunner.dumpAsText();
+  _onload_ = () => {
+    document.documentElement.appendChild(document.createElement('span'));
+    document.documentElement.appendChild(document.createElement('div'));
+    document.body.appendChild(document.createElement('div'));
+    document.execCommand('SelectAll');
+    document.designMode = 'on';
+    document.execCommand('InsertHorizontalRule');
+  };
+</script>
+PASS if no crash or assert.
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (275066 => 275067)


--- trunk/Source/WebCore/ChangeLog	2021-03-25 23:35:20 UTC (rev 275066)
+++ trunk/Source/WebCore/ChangeLog	2021-03-26 00:09:23 UTC (rev 275067)
@@ -1,3 +1,28 @@
+2021-03-25  Zalan Bujtas  <[email protected]>
+
+        [RenderTreeBuilder] Do not try to normalize the tree while destroying the multicolumn flow
+        https://bugs.webkit.org/show_bug.cgi?id=223722
+        <rdar://75731256>
+
+        Reviewed by Simon Fraser.
+
+        Test: fast/multicol/crash-while-destroying-the-column-context.html
+
+        This patch ensures that we don't start moving around parts of the fragmented flow subtree (e.g. collapsing anonymous blocks) while
+        trying place the spanner renderers back to their original positions as part of the "we don't need multicolumn context anymore".
+        (e.g spanner placeholder is removed -> triggers anon block collapsing -> moves subtrees around inside the multicolumn subtree -> insertion happens -> spanner placeholder gets re-validated)
+
+        * rendering/updating/RenderTreeBuilder.cpp:
+        (WebCore::RenderTreeBuilder::destroy):
+        * rendering/updating/RenderTreeBuilder.h:
+        * rendering/updating/RenderTreeBuilderBlock.cpp:
+        (WebCore::RenderTreeBuilder::Block::detach):
+        * rendering/updating/RenderTreeBuilderMultiColumn.cpp:
+        (WebCore::RenderTreeBuilder::MultiColumn::destroyFragmentedFlow):
+        (WebCore::RenderTreeBuilder::MultiColumn::handleSpannerRemoval):
+        (WebCore::RenderTreeBuilder::MultiColumn::multiColumnRelativeWillBeRemoved):
+        * rendering/updating/RenderTreeBuilderMultiColumn.h:
+
 2021-03-25  Andres Gonzalez  <[email protected]>
 
         AX: Consider implementing @aria-details.

Modified: trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp (275066 => 275067)


--- trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp	2021-03-25 23:35:20 UTC (rev 275066)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp	2021-03-26 00:09:23 UTC (rev 275067)
@@ -164,11 +164,11 @@
     s_current = m_previous;
 }
 
-void RenderTreeBuilder::destroy(RenderObject& renderer)
+void RenderTreeBuilder::destroy(RenderObject& renderer, CanCollapseAnonymousBlock canCollapseAnonymousBlock)
 {
     RELEASE_ASSERT(RenderTreeMutationDisallowedScope::isMutationAllowed());
     ASSERT(renderer.parent());
-    auto toDestroy = detach(*renderer.parent(), renderer);
+    auto toDestroy = detach(*renderer.parent(), renderer, canCollapseAnonymousBlock);
 
 #if ENABLE(FULLSCREEN_API)
     if (is<RenderFullScreen>(renderer))

Modified: trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.h (275066 => 275067)


--- trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.h	2021-03-25 23:35:20 UTC (rev 275066)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.h	2021-03-26 00:09:23 UTC (rev 275067)
@@ -48,7 +48,7 @@
     enum class CanCollapseAnonymousBlock { No, Yes };
     RenderPtr<RenderObject> detach(RenderElement&, RenderObject&, CanCollapseAnonymousBlock = CanCollapseAnonymousBlock::Yes) WARN_UNUSED_RETURN;
 
-    void destroy(RenderObject& renderer);
+    void destroy(RenderObject& renderer, CanCollapseAnonymousBlock = CanCollapseAnonymousBlock::Yes);
 
     // NormalizeAfterInsertion::Yes ensures that the destination subtree is consistent after the insertion (anonymous wrappers etc).
     enum class NormalizeAfterInsertion { No, Yes };

Modified: trunk/Source/WebCore/rendering/updating/RenderTreeBuilderBlock.cpp (275066 => 275067)


--- trunk/Source/WebCore/rendering/updating/RenderTreeBuilderBlock.cpp	2021-03-25 23:35:20 UTC (rev 275066)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeBuilderBlock.cpp	2021-03-26 00:09:23 UTC (rev 275067)
@@ -381,7 +381,7 @@
     if (!parent.renderTreeBeingDestroyed()) {
         auto* fragmentedFlow = parent.multiColumnFlow();
         if (fragmentedFlow && fragmentedFlow != &child)
-            m_builder.multiColumnBuilder().multiColumnRelativeWillBeRemoved(*fragmentedFlow, child);
+            m_builder.multiColumnBuilder().multiColumnRelativeWillBeRemoved(*fragmentedFlow, child, canCollapseAnonymousBlock);
     }
     return detach(static_cast<RenderBlock&>(parent), child, canCollapseAnonymousBlock);
 }

Modified: trunk/Source/WebCore/rendering/updating/RenderTreeBuilderMultiColumn.cpp (275066 => 275067)


--- trunk/Source/WebCore/rendering/updating/RenderTreeBuilderMultiColumn.cpp	2021-03-25 23:35:20 UTC (rev 275066)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeBuilderMultiColumn.cpp	2021-03-26 00:09:23 UTC (rev 275067)
@@ -215,7 +215,7 @@
             spannerOriginalParent = &flow;
         // Detaching the spanner takes care of removing the placeholder (and merges the RenderMultiColumnSets).
         auto* spanner = placeholder->spanner();
-        parentAndSpannerList.append(std::make_pair(spannerOriginalParent, m_builder.detach(*spanner->parent(), *spanner)));
+        parentAndSpannerList.append(std::make_pair(spannerOriginalParent, m_builder.detach(*spanner->parent(), *spanner, CanCollapseAnonymousBlock::No)));
     }
     while (auto* columnSet = multiColumnFlow.firstMultiColumnSet())
         m_builder.destroy(*columnSet);
@@ -389,11 +389,11 @@
     return nextDescendant;
 }
 
-void RenderTreeBuilder::MultiColumn::handleSpannerRemoval(RenderMultiColumnFlow& flow, RenderObject& spanner)
+void RenderTreeBuilder::MultiColumn::handleSpannerRemoval(RenderMultiColumnFlow& flow, RenderObject& spanner, RenderTreeBuilder::CanCollapseAnonymousBlock canCollapseAnonymousBlock)
 {
     // The placeholder may already have been removed, but if it hasn't, do so now.
     if (auto placeholder = flow.spannerMap().take(&downcast<RenderBox>(spanner)))
-        m_builder.destroy(*placeholder);
+        m_builder.destroy(*placeholder, canCollapseAnonymousBlock);
 
     if (auto* next = spanner.nextSibling()) {
         if (auto* previous = spanner.previousSibling()) {
@@ -406,7 +406,7 @@
     }
 }
 
-void RenderTreeBuilder::MultiColumn::multiColumnRelativeWillBeRemoved(RenderMultiColumnFlow& flow, RenderObject& relative)
+void RenderTreeBuilder::MultiColumn::multiColumnRelativeWillBeRemoved(RenderMultiColumnFlow& flow, RenderObject& relative, RenderTreeBuilder::CanCollapseAnonymousBlock canCollapseAnonymousBlock)
 {
     flow.invalidateFragments();
     if (is<RenderMultiColumnSpannerPlaceholder>(relative)) {
@@ -421,7 +421,7 @@
         if (relative.parent() != flow.parent())
             return; // not a valid spanner.
 
-        handleSpannerRemoval(flow, relative);
+        handleSpannerRemoval(flow, relative, canCollapseAnonymousBlock);
     }
     // Note that we might end up with empty column sets if all column content is removed. That's no
     // big deal though (and locating them would be expensive), and they will be found and re-used if

Modified: trunk/Source/WebCore/rendering/updating/RenderTreeBuilderMultiColumn.h (275066 => 275067)


--- trunk/Source/WebCore/rendering/updating/RenderTreeBuilderMultiColumn.h	2021-03-25 23:35:20 UTC (rev 275066)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeBuilderMultiColumn.h	2021-03-26 00:09:23 UTC (rev 275067)
@@ -44,7 +44,7 @@
     RenderObject* resolveMovedChild(RenderFragmentedFlow& enclosingFragmentedFlow, RenderObject* beforeChild);
     void restoreColumnSpannersForContainer(const RenderElement& container, RenderMultiColumnFlow&);
     void multiColumnDescendantInserted(RenderMultiColumnFlow&, RenderObject& newDescendant);
-    void multiColumnRelativeWillBeRemoved(RenderMultiColumnFlow&, RenderObject& relative);
+    void multiColumnRelativeWillBeRemoved(RenderMultiColumnFlow&, RenderObject& relative, RenderTreeBuilder::CanCollapseAnonymousBlock);
     static RenderObject* adjustBeforeChildForMultiColumnSpannerIfNeeded(RenderObject& beforeChild);
 
 private:
@@ -51,7 +51,7 @@
     void createFragmentedFlow(RenderBlockFlow&);
     void destroyFragmentedFlow(RenderBlockFlow&);
     RenderObject* processPossibleSpannerDescendant(RenderMultiColumnFlow&, RenderObject*& subtreeRoot, RenderObject& descendant);
-    void handleSpannerRemoval(RenderMultiColumnFlow&, RenderObject& spanner);
+    void handleSpannerRemoval(RenderMultiColumnFlow&, RenderObject& spanner, RenderTreeBuilder::CanCollapseAnonymousBlock);
 
     RenderTreeBuilder& m_builder;
 };
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to