Title: [225255] trunk
Revision
225255
Author
[email protected]
Date
2017-11-28 20:12:32 -0800 (Tue, 28 Nov 2017)

Log Message

Clean up spanners before creating nested column context
https://bugs.webkit.org/show_bug.cgi?id=180107
<rdar://problem/35686655>

Reviewed by Antti Koivisto.

Source/WebCore:

When an existing spanner placeholder is moved into a newly constructed (and nested)
multicolumn context, we figure it's not valid anymore and end up destroying it
(see RenderMultiColumnFlow::fragmentedFlowDescendantInserted).
This is very unfortunate since as we climb back on the stack, we could hit this renderer as
the newly inserted child.

This patch proactively removes the invalid placeholders and moves the associated spanners back to their
original position.

Test: fast/multicol/crash-when-constructing-nested-columns.html

* rendering/RenderMultiColumnFlow.h:
* style/RenderTreeUpdaterMultiColumn.cpp:
(WebCore::RenderTreeUpdater::MultiColumn::createFragmentedFlow):
RenderTreeUpdater::MultiColumn::destroyFragmentedFlow still relies on the placeholder removal
logic in RenderMultiColumnFlow::fragmentedFlowDescendantInserted.

LayoutTests:

* fast/multicol/crash-when-constructing-nested-columns-expected.txt: Added.
* fast/multicol/crash-when-constructing-nested-columns.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (225254 => 225255)


--- trunk/LayoutTests/ChangeLog	2017-11-29 02:59:47 UTC (rev 225254)
+++ trunk/LayoutTests/ChangeLog	2017-11-29 04:12:32 UTC (rev 225255)
@@ -1,3 +1,14 @@
+2017-11-28  Zalan Bujtas  <[email protected]>
+
+        Clean up spanners before creating nested column context
+        https://bugs.webkit.org/show_bug.cgi?id=180107
+        <rdar://problem/35686655>
+        
+        Reviewed by Antti Koivisto.
+
+        * fast/multicol/crash-when-constructing-nested-columns-expected.txt: Added.
+        * fast/multicol/crash-when-constructing-nested-columns.html: Added.
+
 2017-11-28  Wenson Hsieh  <[email protected]>
 
         Allow attachment elements with no appearance to defer rendering to child nodes

Added: trunk/LayoutTests/fast/multicol/crash-when-constructing-nested-columns-expected.txt (0 => 225255)


--- trunk/LayoutTests/fast/multicol/crash-when-constructing-nested-columns-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/multicol/crash-when-constructing-nested-columns-expected.txt	2017-11-29 04:12:32 UTC (rev 225255)
@@ -0,0 +1,2 @@
+PASS if no crash.
+

Added: trunk/LayoutTests/fast/multicol/crash-when-constructing-nested-columns.html (0 => 225255)


--- trunk/LayoutTests/fast/multicol/crash-when-constructing-nested-columns.html	                        (rev 0)
+++ trunk/LayoutTests/fast/multicol/crash-when-constructing-nested-columns.html	2017-11-29 04:12:32 UTC (rev 225255)
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<body>
+PASS if no crash.
+<div style="columns: 2;"><div id=nestedColumn><div style="column-span:all;"></div></div></div>
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+document.body.offsetTop;
+nestedColumn.style.columns = "2";
+</script>
+</html>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (225254 => 225255)


--- trunk/Source/WebCore/ChangeLog	2017-11-29 02:59:47 UTC (rev 225254)
+++ trunk/Source/WebCore/ChangeLog	2017-11-29 04:12:32 UTC (rev 225255)
@@ -1,3 +1,28 @@
+2017-11-28  Zalan Bujtas  <[email protected]>
+
+        Clean up spanners before creating nested column context
+        https://bugs.webkit.org/show_bug.cgi?id=180107
+        <rdar://problem/35686655>
+        
+        Reviewed by Antti Koivisto.
+
+        When an existing spanner placeholder is moved into a newly constructed (and nested)
+        multicolumn context, we figure it's not valid anymore and end up destroying it
+        (see RenderMultiColumnFlow::fragmentedFlowDescendantInserted).
+        This is very unfortunate since as we climb back on the stack, we could hit this renderer as
+        the newly inserted child. 
+
+        This patch proactively removes the invalid placeholders and moves the associated spanners back to their
+        original position. 
+
+        Test: fast/multicol/crash-when-constructing-nested-columns.html
+
+        * rendering/RenderMultiColumnFlow.h:
+        * style/RenderTreeUpdaterMultiColumn.cpp:
+        (WebCore::RenderTreeUpdater::MultiColumn::createFragmentedFlow): 
+        RenderTreeUpdater::MultiColumn::destroyFragmentedFlow still relies on the placeholder removal
+        logic in RenderMultiColumnFlow::fragmentedFlowDescendantInserted.
+
 2017-11-28  Tim Horton  <[email protected]>
 
         REGRESSION (High Sierra): Layout Test fast/multicol/newmulticol/spanner2.html is a flaky image failure on WK1

Modified: trunk/Source/WebCore/rendering/RenderMultiColumnFlow.h (225254 => 225255)


--- trunk/Source/WebCore/rendering/RenderMultiColumnFlow.h	2017-11-29 02:59:47 UTC (rev 225254)
+++ trunk/Source/WebCore/rendering/RenderMultiColumnFlow.h	2017-11-29 04:12:32 UTC (rev 225255)
@@ -96,6 +96,7 @@
     bool shouldCheckColumnBreaks() const override;
 
     typedef HashMap<RenderBox*, WeakPtr<RenderMultiColumnSpannerPlaceholder>> SpannerMap;
+    SpannerMap& spannerMap() { return *m_spannerMap; }
     std::unique_ptr<SpannerMap> takeSpannerMap() { return WTFMove(m_spannerMap); }
 
 private:
@@ -119,8 +120,6 @@
     void handleSpannerRemoval(RenderObject& spanner);
     RenderObject* processPossibleSpannerDescendant(RenderObject*& subtreeRoot, RenderObject& descendant);
 
-    SpannerMap& spannerMap() { return *m_spannerMap; }
-    
 private:
     std::unique_ptr<SpannerMap> m_spannerMap;
 

Modified: trunk/Source/WebCore/style/RenderTreeUpdaterMultiColumn.cpp (225254 => 225255)


--- trunk/Source/WebCore/style/RenderTreeUpdaterMultiColumn.cpp	2017-11-29 02:59:47 UTC (rev 225254)
+++ trunk/Source/WebCore/style/RenderTreeUpdaterMultiColumn.cpp	2017-11-29 04:12:32 UTC (rev 225255)
@@ -49,10 +49,36 @@
 
 void RenderTreeUpdater::MultiColumn::createFragmentedFlow(RenderBlockFlow& flow)
 {
+    flow.setChildrenInline(false); // Do this to avoid wrapping inline children that are just going to move into the flow thread.
+    flow.deleteLines();
+    // If this soon-to-be multicolumn flow is already part of a multicolumn context, we need to move back the descendant spanners
+    // to their original position before moving subtrees around.
+    auto* enclosingflow = flow.enclosingFragmentedFlow();
+    if (is<RenderMultiColumnFlow>(enclosingflow)) {
+        auto& spanners = downcast<RenderMultiColumnFlow>(enclosingflow)->spannerMap();
+        Vector<RenderMultiColumnSpannerPlaceholder*> placeholdersToDelete;
+        for (auto& spannerAndPlaceholder : spanners) {
+            auto& placeholder = *spannerAndPlaceholder.value;
+            if (!placeholder.isDescendantOf(&flow))
+                continue;
+            placeholdersToDelete.append(&placeholder);
+        }
+        for (auto* placeholder : placeholdersToDelete) {
+            auto* spanner = placeholder->spanner();
+            if (!spanner) {
+                ASSERT_NOT_REACHED();
+                continue;
+            }
+            // Move the spanner back to its original position.
+            auto& spannerOriginalParent = *placeholder->parent();
+            // Detaching the spanner takes care of removing the placeholder (and merges the RenderMultiColumnSets).
+            auto spannerToReInsert = spanner->parent()->takeChild(*spanner);
+            spannerOriginalParent.addChild(WTFMove(spannerToReInsert));
+        }
+    }
+
     auto newFragmentedFlow = WebCore::createRenderer<RenderMultiColumnFlow>(flow.document(), RenderStyle::createAnonymousStyleWithDisplay(flow.style(), BLOCK));
     newFragmentedFlow->initializeStyle();
-    flow.setChildrenInline(false); // Do this to avoid wrapping inline children that are just going to move into the flow thread.
-    flow.deleteLines();
     auto& fragmentedFlow = *newFragmentedFlow;
     flow.RenderBlock::addChild(WTFMove(newFragmentedFlow));
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to