Title: [255971] trunk
Revision
255971
Author
aj...@chromium.org
Date
2020-02-06 11:54:37 -0800 (Thu, 06 Feb 2020)

Log Message

Crash in RenderTableCol::willBeRemovedFromTree()
https://bugs.webkit.org/show_bug.cgi?id=207031

Reviewed by Antti Koivisto.

Source/WebCore:

A RenderTableCol's table() can be null during willBeRemovedFromTree. This can
happen when the RenderTableCol's table is an ancestor rather than a direct
parent. If RenderTreeBuilder::destroy is then called on an ancestor of the
the RenderTableCol's table, RenderTreeBuilder::destroy proceeds down the ancestor
chain, detaching each node along the way. By the time the RenderTableCol is
reached, the table (a non-parent ancestor) has already been detached, so
table() is null and we crash while trying to use it.

The underlying bug is that RenderTreeBuilder::destroyAndCleanUpAnonymousWrappers
is getting called on the RenderTableCol's ancestor before its descendants (including
the RenderTableCol) are destroyed.

Fix this by changing the order of operations in RenderTreeUpdater::tearDownRenderers
so that tearDownLeftoverShadowHostChildren happens before destroyAndCleanUpAnonymousWrappers.
This ensures that the RenderTableCol is destroyed before destroyAndCleanUpAnonymousWrappers is
called on its ancestor.

Test: tables/table-col-indent-crash.html

* rendering/updating/RenderTreeUpdater.cpp:
(WebCore::RenderTreeUpdater::tearDownRenderers):

LayoutTests:

* tables/table-col-indent-crash-expected.txt: Added.
* tables/table-col-indent-crash.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (255970 => 255971)


--- trunk/LayoutTests/ChangeLog	2020-02-06 19:53:08 UTC (rev 255970)
+++ trunk/LayoutTests/ChangeLog	2020-02-06 19:54:37 UTC (rev 255971)
@@ -1,3 +1,13 @@
+2020-02-06  Ali Juma  <aj...@chromium.org>
+
+        Crash in RenderTableCol::willBeRemovedFromTree()
+        https://bugs.webkit.org/show_bug.cgi?id=207031
+
+        Reviewed by Antti Koivisto.
+
+        * tables/table-col-indent-crash-expected.txt: Added.
+        * tables/table-col-indent-crash.html: Added.
+
 2020-02-06  Jason Lawrence  <lawrenc...@apple.com>
 
         Regression: (r255150?) [ Mac wk1 ] http/wpt/css/css-animations/start-animation-001.html is flaky failing.

Added: trunk/LayoutTests/tables/table-col-indent-crash-expected.txt (0 => 255971)


--- trunk/LayoutTests/tables/table-col-indent-crash-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/tables/table-col-indent-crash-expected.txt	2020-02-06 19:54:37 UTC (rev 255971)
@@ -0,0 +1,3 @@
+ 
+This test passes if it doesn't crash.
+

Added: trunk/LayoutTests/tables/table-col-indent-crash.html (0 => 255971)


--- trunk/LayoutTests/tables/table-col-indent-crash.html	                        (rev 0)
+++ trunk/LayoutTests/tables/table-col-indent-crash.html	2020-02-06 19:54:37 UTC (rev 255971)
@@ -0,0 +1,25 @@
+<style>
+   body { -webkit-user-modify: read-write; }
+</style>
+
+<script>
+window._onload_ = function() {
+    if (window.testRunner)
+        testRunner.dumpAsText();
+    window.getSelection().setPosition(tableElement);
+    document.execCommand("indent", false);
+    document.execCommand("indent", false);
+}
+</script>
+
+<body>
+  <template></template>
+  <details id="details">
+    <summary>
+      <table id="tableElement">
+        <br/>
+        <col>This test passes if it doesn't crash.</col>
+      </table>
+    </summary>
+  </details>
+</body>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (255970 => 255971)


--- trunk/Source/WebCore/ChangeLog	2020-02-06 19:53:08 UTC (rev 255970)
+++ trunk/Source/WebCore/ChangeLog	2020-02-06 19:54:37 UTC (rev 255971)
@@ -1,3 +1,32 @@
+2020-02-06  Ali Juma  <aj...@chromium.org>
+
+        Crash in RenderTableCol::willBeRemovedFromTree()
+        https://bugs.webkit.org/show_bug.cgi?id=207031
+
+        Reviewed by Antti Koivisto.
+
+        A RenderTableCol's table() can be null during willBeRemovedFromTree. This can
+        happen when the RenderTableCol's table is an ancestor rather than a direct
+        parent. If RenderTreeBuilder::destroy is then called on an ancestor of the
+        the RenderTableCol's table, RenderTreeBuilder::destroy proceeds down the ancestor
+        chain, detaching each node along the way. By the time the RenderTableCol is
+        reached, the table (a non-parent ancestor) has already been detached, so
+        table() is null and we crash while trying to use it.
+
+        The underlying bug is that RenderTreeBuilder::destroyAndCleanUpAnonymousWrappers
+        is getting called on the RenderTableCol's ancestor before its descendants (including
+        the RenderTableCol) are destroyed.
+
+        Fix this by changing the order of operations in RenderTreeUpdater::tearDownRenderers
+        so that tearDownLeftoverShadowHostChildren happens before destroyAndCleanUpAnonymousWrappers.
+        This ensures that the RenderTableCol is destroyed before destroyAndCleanUpAnonymousWrappers is
+        called on its ancestor.
+
+        Test: tables/table-col-indent-crash.html
+
+        * rendering/updating/RenderTreeUpdater.cpp:
+        (WebCore::RenderTreeUpdater::tearDownRenderers):
+
 2020-02-06  Brent Fulgham  <bfulg...@apple.com>
 
         Prevent navigating top level frames to Data URLs

Modified: trunk/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp (255970 => 255971)


--- trunk/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp	2020-02-06 19:53:08 UTC (rev 255970)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp	2020-02-06 19:54:37 UTC (rev 255971)
@@ -561,6 +561,10 @@
         while (teardownStack.size() > depth) {
             auto& element = *teardownStack.takeLast();
 
+            // Make sure we don't leave any renderers behind in nodes outside the composed tree.
+            if (element.shadowRoot())
+                tearDownLeftoverShadowHostChildren(element, builder);
+
             switch (teardownType) {
             case TeardownType::Full:
             case TeardownType::RendererUpdateCancelingAnimations:
@@ -589,10 +593,6 @@
                 element.setRenderer(nullptr);
             }
 
-            // Make sure we don't leave any renderers behind in nodes outside the composed tree.
-            if (element.shadowRoot())
-                tearDownLeftoverShadowHostChildren(element, builder);
-
             if (element.hasCustomStyleResolveCallbacks())
                 element.didDetachRenderers();
         }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to