diff --git a/third_party/blink/renderer/core/dom/container_node.cc b/third_party/blink/renderer/core/dom/container_node.cc index b463af62da8e54..28566c88b5a8d8 100644 --- a/third_party/blink/renderer/core/dom/container_node.cc +++ b/third_party/blink/renderer/core/dom/container_node.cc @@ -280,8 +280,19 @@ bool ContainerNode::EnsurePreInsertionValidity( if (!CheckReferenceChildParent(*this, next, old_child, exception_state)) return false; // Step 4-6. - return document->CanAcceptChild(new_child, new_children, next, old_child, - exception_state); + if (!document->CanAcceptChild(new_child, new_children, next, old_child, + exception_state)) { + return false; + } + // See the matching check below for non-Document parents. + if (new_children && new_children->size() != 1u && + RuntimeEnabledFeatures:: + RecheckParentDuringNodeVectorInsertionEnabled() && + !RecheckNodeInsertionStructuralPrereq(*new_children, next, + exception_state)) { + return false; + } + return true; } // 2. If node is a host-including inclusive ancestor of parent, throw a diff --git a/third_party/blink/renderer/core/dom/container_node_test.cc b/third_party/blink/renderer/core/dom/container_node_test.cc index 28aeb846c7d009..942f887f0f2ab6 100644 --- a/third_party/blink/renderer/core/dom/container_node_test.cc +++ b/third_party/blink/renderer/core/dom/container_node_test.cc @@ -4,11 +4,17 @@ #include "third_party/blink/renderer/core/dom/container_node.h" +#include "third_party/blink/renderer/core/dom/comment.h" #include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/dom/dom_implementation.h" #include "third_party/blink/renderer/core/dom/text.h" +#include "third_party/blink/renderer/core/dom/xml_document.h" #include "third_party/blink/renderer/core/editing/testing/editing_test_base.h" #include "third_party/blink/renderer/core/execution_context/agent.h" +#include "third_party/blink/renderer/core/html/html_div_element.h" +#include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/script_regexp.h" +#include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -144,4 +150,29 @@ TEST_F(ContainerNodeTest, CanFindOnlyTextNodesThatMatch) { GetDocument().getElementById(AtomicString("id_2"))->firstChild()); } +TEST_F(ContainerNodeTest, AppendChildrenToDocumentRechecksParent) { + Document& document = GetDocument(); + XMLDocument* target = document.implementation().createDocument( + g_null_atom, g_null_atom, nullptr, ASSERT_NO_EXCEPTION); + + auto* div = MakeGarbageCollected(document); + Comment* node1 = Comment::Create(document, "a"); + Comment* node2 = Comment::Create(document, "b"); + div->AppendChild(node1); + + HeapVector> new_children; + new_children.push_back(node1); + new_children.push_back(node2); + + DummyExceptionStateForTesting exception_state; + target->AppendChildren(new_children, exception_state); + + EXPECT_FALSE(exception_state.HadException()); + EXPECT_EQ(nullptr, target->firstChild()); + EXPECT_EQ(div, node1->parentNode()); + EXPECT_EQ(nullptr, node2->parentNode()); + EXPECT_EQ(node1, div->firstChild()); + EXPECT_EQ(node1, div->lastChild()); +} + } // namespace blink diff --git a/third_party/blink/web_tests/external/wpt/dom/nodes/crashtests/multiple-append-to-document-mutated-in-unload.https.html b/third_party/blink/web_tests/external/wpt/dom/nodes/crashtests/multiple-append-to-document-mutated-in-unload.https.html new file mode 100644 index 00000000000000..a5b9cca4ad317b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/dom/nodes/crashtests/multiple-append-to-document-mutated-in-unload.https.html @@ -0,0 +1,25 @@ + +
+ +
+ +
diff --git a/third_party/blink/web_tests/external/wpt/dom/nodes/crashtests/multiple-append-to-document-mutated-in-unload.https.html.headers b/third_party/blink/web_tests/external/wpt/dom/nodes/crashtests/multiple-append-to-document-mutated-in-unload.https.html.headers new file mode 100644 index 00000000000000..f1e8ace831407e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/dom/nodes/crashtests/multiple-append-to-document-mutated-in-unload.https.html.headers @@ -0,0 +1 @@ +Permissions-Policy: unload=*