Title: [277373] trunk
Revision
277373
Author
[email protected]
Date
2021-05-12 10:13:20 -0700 (Wed, 12 May 2021)

Log Message

Source/WebCore:
REGRESSION: Release assert in SlotAssignment::assignedNodesForSlot via ComposedTreeIterator::traverseNextInShadowTree
in Element::insertedIntoAncestor
https://bugs.webkit.org/show_bug.cgi?id=225684

Reviewed by Darin Adler.

The release assertion failure was caused by RenderTreeUpdater::tearDownRenderers end up traversing the parts of the DOM
for which Element::insertedIntoAncestor had not been called yet. Since HTMLSlotElement::insertedIntoAncestor is where
SlotAssignment::Slot is updated for a newly inserted slot, SlotAssignment::Slot may not contain this slot element.

Fixed the bug by returning early in SlotAssignment::assignedNodesForSlot when this condition holds, which is when
the shadow root is connected to a document but HTMLSlotElement isn't since its connected flag has not been updated yet.

Test: fast/shadow-dom/insert-host-child-with-slot-renderer-teardown-crash.html

* dom/SlotAssignment.cpp:
(WebCore::SlotAssignment::assignedNodesForSlot):

LayoutTests:
REGRESSION: Release assert in SlotAssignment::assignedNodesForSlot via ComposedTreeIterator::traverseNextInShadowTree in Element::insertedIntoAncestor
https://bugs.webkit.org/show_bug.cgi?id=225684

Reviewed by Darin Adler.

Added a regression test.

* fast/shadow-dom/insert-host-child-with-slot-renderer-teardown-crash-expected.txt: Added.
* fast/shadow-dom/insert-host-child-with-slot-renderer-teardown-crash.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (277372 => 277373)


--- trunk/LayoutTests/ChangeLog	2021-05-12 16:59:44 UTC (rev 277372)
+++ trunk/LayoutTests/ChangeLog	2021-05-12 17:13:20 UTC (rev 277373)
@@ -1,3 +1,15 @@
+2021-05-12  Ryosuke Niwa  <[email protected]>
+
+        REGRESSION: Release assert in SlotAssignment::assignedNodesForSlot via ComposedTreeIterator::traverseNextInShadowTree in Element::insertedIntoAncestor
+        https://bugs.webkit.org/show_bug.cgi?id=225684
+
+        Reviewed by Darin Adler.
+
+        Added a regression test.
+
+        * fast/shadow-dom/insert-host-child-with-slot-renderer-teardown-crash-expected.txt: Added.
+        * fast/shadow-dom/insert-host-child-with-slot-renderer-teardown-crash.html: Added.
+
 2021-05-12  Sergio Villar Senin  <[email protected]>
 
         [css-flexbox] Do not use margins when computing aspect ratio cross sizes

Added: trunk/LayoutTests/fast/shadow-dom/insert-host-child-with-slot-renderer-teardown-crash-expected.txt (0 => 277373)


--- trunk/LayoutTests/fast/shadow-dom/insert-host-child-with-slot-renderer-teardown-crash-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/insert-host-child-with-slot-renderer-teardown-crash-expected.txt	2021-05-12 17:13:20 UTC (rev 277373)
@@ -0,0 +1,3 @@
+This tests if WebKit does not crash or hit any assertions.
+
+PASS

Added: trunk/LayoutTests/fast/shadow-dom/insert-host-child-with-slot-renderer-teardown-crash.html (0 => 277373)


--- trunk/LayoutTests/fast/shadow-dom/insert-host-child-with-slot-renderer-teardown-crash.html	                        (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/insert-host-child-with-slot-renderer-teardown-crash.html	2021-05-12 17:13:20 UTC (rev 277373)
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<body>
+<p>This tests if WebKit does not crash or hit any assertions.</p>
+<script>
+
+if (window.testRunner)
+    testRunner.dumpAsText();
+
+const host = document.createElement('div');
+document.body.appendChild(host);
+const shadowRoot = host.attachShadow({mode: 'closed'});
+shadowRoot.innerHTML = '<div id="inner"><slot name="some-name"></slot></div>';
+
+const innerHost = shadowRoot.getElementById('inner');
+const innerShadowRoot = innerHost.attachShadow({mode: 'closed'});
+innerShadowRoot.appendChild(document.createElement('slot'));
+innerHost.getBoundingClientRect();
+
+shadowRoot.querySelector('slot').remove();
+const newChild = document.createElement('div');
+newChild.appendChild(document.createElement('slot'));
+innerHost.appendChild(newChild);
+
+document.write('<div>PASS</div>');
+
+</script>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (277372 => 277373)


--- trunk/Source/WebCore/ChangeLog	2021-05-12 16:59:44 UTC (rev 277372)
+++ trunk/Source/WebCore/ChangeLog	2021-05-12 17:13:20 UTC (rev 277373)
@@ -1,3 +1,23 @@
+2021-05-12  Ryosuke Niwa  <[email protected]>
+
+        REGRESSION: Release assert in SlotAssignment::assignedNodesForSlot via ComposedTreeIterator::traverseNextInShadowTree
+        in Element::insertedIntoAncestor
+        https://bugs.webkit.org/show_bug.cgi?id=225684
+
+        Reviewed by Darin Adler.
+
+        The release assertion failure was caused by RenderTreeUpdater::tearDownRenderers end up traversing the parts of the DOM
+        for which Element::insertedIntoAncestor had not been called yet. Since HTMLSlotElement::insertedIntoAncestor is where
+        SlotAssignment::Slot is updated for a newly inserted slot, SlotAssignment::Slot may not contain this slot element.
+
+        Fixed the bug by returning early in SlotAssignment::assignedNodesForSlot when this condition holds, which is when
+        the shadow root is connected to a document but HTMLSlotElement isn't since its connected flag has not been updated yet.
+
+        Test: fast/shadow-dom/insert-host-child-with-slot-renderer-teardown-crash.html
+
+        * dom/SlotAssignment.cpp:
+        (WebCore::SlotAssignment::assignedNodesForSlot):
+
 2021-05-12  Peng Liu  <[email protected]>
 
         Implement TextTrackPrivateRemote::inBandMetadataTrackDispatchType()

Modified: trunk/Source/WebCore/dom/SlotAssignment.cpp (277372 => 277373)


--- trunk/Source/WebCore/dom/SlotAssignment.cpp	2021-05-12 16:59:44 UTC (rev 277372)
+++ trunk/Source/WebCore/dom/SlotAssignment.cpp	2021-05-12 17:13:20 UTC (rev 277373)
@@ -332,6 +332,10 @@
     ASSERT(slotElement.containingShadowRoot() == &shadowRoot);
     const AtomString& slotName = slotNameFromAttributeValue(slotElement.attributeWithoutSynchronization(nameAttr));
     auto* slot = m_slots.get(slotName);
+
+    bool hasNotCalledInsertedIntoAncestorOnSlot = shadowRoot.isConnected() && !slotElement.isConnected();
+    if (hasNotCalledInsertedIntoAncestorOnSlot)
+        return nullptr;
     RELEASE_ASSERT(slot);
 
     if (!m_slotAssignmentsIsValid)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to