Title: [244012] releases/WebKitGTK/webkit-2.24
Revision
244012
Author
[email protected]
Date
2019-04-08 05:39:34 -0700 (Mon, 08 Apr 2019)

Log Message

Merge r243233 - appendChild should throw when inserting an ancestor of a template into its content adopted to another document
https://bugs.webkit.org/show_bug.cgi?id=195984

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

Rebaselined the test that is not fully passing.

* web-platform-tests/html/semantics/scripting-1/the-template-element/template-element/template-content-hierarcy-expected.txt:

Source/WebCore:

The WPT test caught a bug that appendChild and other DOM insertion functions were incorrectly assuming that
any node that's in a HTML template element has the current document's template document as its owner.
The assumption is wrong when the template element's content DocumentFragment is adopted to another document.

Fixed the bug by always checking the ancestor host elements in checkAcceptChild. Also

Test: fast/dom/insert-template-parent-into-adopted-content.html

* dom/ContainerNode.cpp:
(WebCore::isInTemplateContent): Deleted. This code is simply wrong.
(WebCore::containsConsideringHostElements): Deleted. Call sites are updated to use containsIncludingHostElements.
(WebCore::containsIncludingHostElements): Moved from Node.cpp and optimized this code a bit. It's more efficient
to get the parent node and check for ShadowRoot and DocumentFragment only when the parent is null than to check
for those two node types before getting the parent node.
(WebCore::checkAcceptChild): Merged two code paths to call containsIncludingHostElements. The early return for
a pseudo element is there only to prevent tree corruption in release build even in the presence of a major bug
so it shouldn't be an spec compliance issue.
* dom/Node.cpp:
(WebCore::Node::containsIncludingHostElements const): Deleted.
* dom/Node.h:

LayoutTests:

Added a regression test.

* fast/dom/insert-template-parent-into-adopted-content-expected.txt: Added.
* fast/dom/insert-template-parent-into-adopted-content.html: Added.

Modified Paths

Added Paths

Diff

Modified: releases/WebKitGTK/webkit-2.24/LayoutTests/ChangeLog (244011 => 244012)


--- releases/WebKitGTK/webkit-2.24/LayoutTests/ChangeLog	2019-04-08 12:39:27 UTC (rev 244011)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/ChangeLog	2019-04-08 12:39:34 UTC (rev 244012)
@@ -1,5 +1,17 @@
 2019-03-19  Ryosuke Niwa  <[email protected]>
 
+        appendChild should throw when inserting an ancestor of a template into its content adopted to another document
+        https://bugs.webkit.org/show_bug.cgi?id=195984
+
+        Reviewed by Darin Adler.
+
+        Added a regression test.
+
+        * fast/dom/insert-template-parent-into-adopted-content-expected.txt: Added.
+        * fast/dom/insert-template-parent-into-adopted-content.html: Added.
+
+2019-03-19  Ryosuke Niwa  <[email protected]>
+
         Rebaseline the test after r243175. It got somehow landed with failing expectations.
 
         * fast/dom/replace-child-with-mutation-event-removal-and-circular-template-insertion-expected.txt:

Added: releases/WebKitGTK/webkit-2.24/LayoutTests/fast/dom/insert-template-parent-into-adopted-content-expected.txt (0 => 244012)


--- releases/WebKitGTK/webkit-2.24/LayoutTests/fast/dom/insert-template-parent-into-adopted-content-expected.txt	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/fast/dom/insert-template-parent-into-adopted-content-expected.txt	2019-04-08 12:39:34 UTC (rev 244012)
@@ -0,0 +1,13 @@
+This tests inserting the parent of a template element into its content document fragment
+after adopting the document fragment to another document. WebKit should throw HierarchyRequestError
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS template.content.appendChild(templateParent) threw exception HierarchyRequestError: The operation would yield an incorrect node tree..
+PASS template.content.insertBefore(templateParent, template.content.firstChild) threw exception HierarchyRequestError: The operation would yield an incorrect node tree..
+PASS template.content.replaceChild(templateParent, template.content.firstChild) threw exception HierarchyRequestError: The operation would yield an incorrect node tree..
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: releases/WebKitGTK/webkit-2.24/LayoutTests/fast/dom/insert-template-parent-into-adopted-content.html (0 => 244012)


--- releases/WebKitGTK/webkit-2.24/LayoutTests/fast/dom/insert-template-parent-into-adopted-content.html	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/fast/dom/insert-template-parent-into-adopted-content.html	2019-04-08 12:39:34 UTC (rev 244012)
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<body>
+<div id="templateParent"><template id="template"><span></span></template></div>
+<script src=""
+<script>
+
+description('This tests inserting the parent of a template element into its content document fragment<br>'
+    + 'after adopting the document fragment to another document. WebKit should throw HierarchyRequestError');
+
+const newDocument = document.implementation.createHTMLDocument();
+newDocument.adoptNode(template.content);
+shouldThrowErrorName('template.content.appendChild(templateParent)', 'HierarchyRequestError');
+shouldThrowErrorName('template.content.insertBefore(templateParent, template.content.firstChild)', 'HierarchyRequestError');
+shouldThrowErrorName('template.content.replaceChild(templateParent, template.content.firstChild)', 'HierarchyRequestError');
+
+</script>
+</body>
+</html>

Modified: releases/WebKitGTK/webkit-2.24/LayoutTests/imported/w3c/ChangeLog (244011 => 244012)


--- releases/WebKitGTK/webkit-2.24/LayoutTests/imported/w3c/ChangeLog	2019-04-08 12:39:27 UTC (rev 244011)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/imported/w3c/ChangeLog	2019-04-08 12:39:34 UTC (rev 244012)
@@ -1,3 +1,14 @@
+2019-03-19  Ryosuke Niwa  <[email protected]>
+
+        appendChild should throw when inserting an ancestor of a template into its content adopted to another document
+        https://bugs.webkit.org/show_bug.cgi?id=195984
+
+        Reviewed by Darin Adler.
+
+        Rebaselined the test that is not fully passing.
+
+        * web-platform-tests/html/semantics/scripting-1/the-template-element/template-element/template-content-hierarcy-expected.txt:
+
 2019-03-22  Alicia Boya GarcĂ­a  <[email protected]>
 
         [MSE][GStreamer] Don't construct segments on PlaybackPipeline::flush

Modified: releases/WebKitGTK/webkit-2.24/LayoutTests/imported/w3c/web-platform-tests/html/semantics/scripting-1/the-template-element/template-element/template-content-hierarcy-expected.txt (244011 => 244012)


--- releases/WebKitGTK/webkit-2.24/LayoutTests/imported/w3c/web-platform-tests/html/semantics/scripting-1/the-template-element/template-element/template-content-hierarcy-expected.txt	2019-04-08 12:39:27 UTC (rev 244011)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/imported/w3c/web-platform-tests/html/semantics/scripting-1/the-template-element/template-element/template-content-hierarcy-expected.txt	2019-04-08 12:39:34 UTC (rev 244012)
@@ -1,6 +1,4 @@
 
 PASS Template content should throw when its ancestor is being appended. 
-FAIL Template content should throw exception when its ancestor in a different document but connected via host is being append. assert_throws: Template content should throw if any of ancestor is being appended. function "() => {
-    tmpl.content.appendChild(parent);
-  }" did not throw
+PASS Template content should throw exception when its ancestor in a different document but connected via host is being append. 
 

Modified: releases/WebKitGTK/webkit-2.24/Source/WebCore/ChangeLog (244011 => 244012)


--- releases/WebKitGTK/webkit-2.24/Source/WebCore/ChangeLog	2019-04-08 12:39:27 UTC (rev 244011)
+++ releases/WebKitGTK/webkit-2.24/Source/WebCore/ChangeLog	2019-04-08 12:39:34 UTC (rev 244012)
@@ -1,5 +1,33 @@
 2019-03-19  Ryosuke Niwa  <[email protected]>
 
+        appendChild should throw when inserting an ancestor of a template into its content adopted to another document
+        https://bugs.webkit.org/show_bug.cgi?id=195984
+
+        Reviewed by Darin Adler.
+
+        The WPT test caught a bug that appendChild and other DOM insertion functions were incorrectly assuming that
+        any node that's in a HTML template element has the current document's template document as its owner.
+        The assumption is wrong when the template element's content DocumentFragment is adopted to another document.
+
+        Fixed the bug by always checking the ancestor host elements in checkAcceptChild. Also
+
+        Test: fast/dom/insert-template-parent-into-adopted-content.html
+
+        * dom/ContainerNode.cpp:
+        (WebCore::isInTemplateContent): Deleted. This code is simply wrong.
+        (WebCore::containsConsideringHostElements): Deleted. Call sites are updated to use containsIncludingHostElements.
+        (WebCore::containsIncludingHostElements): Moved from Node.cpp and optimized this code a bit. It's more efficient
+        to get the parent node and check for ShadowRoot and DocumentFragment only when the parent is null than to check
+        for those two node types before getting the parent node.
+        (WebCore::checkAcceptChild): Merged two code paths to call containsIncludingHostElements. The early return for
+        a pseudo element is there only to prevent tree corruption in release build even in the presence of a major bug
+        so it shouldn't be an spec compliance issue.
+        * dom/Node.cpp:
+        (WebCore::Node::containsIncludingHostElements const): Deleted.
+        * dom/Node.h:
+
+2019-03-19  Ryosuke Niwa  <[email protected]>
+
         Reparenting during a mutation event inside appendChild could result in a circular DOM tree
         https://bugs.webkit.org/show_bug.cgi?id=192825
 

Modified: releases/WebKitGTK/webkit-2.24/Source/WebCore/dom/ContainerNode.cpp (244011 => 244012)


--- releases/WebKitGTK/webkit-2.24/Source/WebCore/dom/ContainerNode.cpp	2019-04-08 12:39:27 UTC (rev 244011)
+++ releases/WebKitGTK/webkit-2.24/Source/WebCore/dom/ContainerNode.cpp	2019-04-08 12:39:34 UTC (rev 244012)
@@ -292,27 +292,34 @@
     return true;
 }
 
-static inline bool isInTemplateContent(const Node* node)
+static bool containsIncludingHostElements(const Node& possibleAncestor, const Node& node)
 {
-    Document& document = node->document();
-    return &document == document.templateDocument();
-}
+    const Node* currentNode = &node;
+    do {
+        if (currentNode == &possibleAncestor)
+            return true;
+        const ContainerNode* parent = currentNode->parentNode();
+        if (!parent) {
+            if (is<ShadowRoot>(currentNode))
+                parent = downcast<ShadowRoot>(currentNode)->host();
+            else if (is<DocumentFragment>(*currentNode) && downcast<DocumentFragment>(*currentNode).isTemplateContent())
+                parent = static_cast<const TemplateContentDocumentFragment*>(currentNode)->host();
+        }
+        currentNode = parent;
+    } while (currentNode);
 
-static inline bool containsConsideringHostElements(const Node& newChild, const Node& newParent)
-{
-    return (newParent.isInShadowTree() || isInTemplateContent(&newParent))
-        ? newChild.containsIncludingHostElements(&newParent)
-        : newChild.contains(&newParent);
+    return false;
 }
 
 static inline ExceptionOr<void> checkAcceptChild(ContainerNode& newParent, Node& newChild, const Node* refChild, Document::AcceptChildOperation operation)
 {
+    if (containsIncludingHostElements(newChild, newParent))
+        return Exception { HierarchyRequestError };
+
     // Use common case fast path if possible.
     if ((newChild.isElementNode() || newChild.isTextNode()) && newParent.isElementNode()) {
         ASSERT(!newParent.isDocumentTypeNode());
         ASSERT(isChildTypeAllowed(newParent, newChild));
-        if (containsConsideringHostElements(newChild, newParent))
-            return Exception { HierarchyRequestError };
         if (operation == Document::AcceptChildOperation::InsertOrAdd && refChild && refChild->parentNode() != &newParent)
             return Exception { NotFoundError };
         return { };
@@ -323,9 +330,6 @@
     if (newChild.isPseudoElement())
         return Exception { HierarchyRequestError };
 
-    if (containsConsideringHostElements(newChild, newParent))
-        return Exception { HierarchyRequestError };
-
     if (operation == Document::AcceptChildOperation::InsertOrAdd && refChild && refChild->parentNode() != &newParent)
         return Exception { NotFoundError };
 
@@ -342,7 +346,7 @@
 {
     ASSERT(!newParent.isDocumentTypeNode());
     ASSERT(isChildTypeAllowed(newParent, newChild));
-    if (containsConsideringHostElements(newChild, newParent))
+    if (containsIncludingHostElements(newChild, newParent))
         return Exception { HierarchyRequestError };
     return { };
 }

Modified: releases/WebKitGTK/webkit-2.24/Source/WebCore/dom/Node.cpp (244011 => 244012)


--- releases/WebKitGTK/webkit-2.24/Source/WebCore/dom/Node.cpp	2019-04-08 12:39:27 UTC (rev 244011)
+++ releases/WebKitGTK/webkit-2.24/Source/WebCore/dom/Node.cpp	2019-04-08 12:39:34 UTC (rev 244012)
@@ -1030,19 +1030,6 @@
     return false;
 }
 
-bool Node::containsIncludingHostElements(const Node* node) const
-{
-    while (node) {
-        if (node == this)
-            return true;
-        if (is<DocumentFragment>(*node) && downcast<DocumentFragment>(*node).isTemplateContent())
-            node = static_cast<const TemplateContentDocumentFragment*>(node)->host();
-        else
-            node = node->parentOrShadowHostNode();
-    }
-    return false;
-}
-
 Node* Node::pseudoAwarePreviousSibling() const
 {
     Element* parentOrHost = is<PseudoElement>(*this) ? downcast<PseudoElement>(*this).hostElement() : parentElement();

Modified: releases/WebKitGTK/webkit-2.24/Source/WebCore/dom/Node.h (244011 => 244012)


--- releases/WebKitGTK/webkit-2.24/Source/WebCore/dom/Node.h	2019-04-08 12:39:27 UTC (rev 244011)
+++ releases/WebKitGTK/webkit-2.24/Source/WebCore/dom/Node.h	2019-04-08 12:39:34 UTC (rev 244012)
@@ -392,7 +392,6 @@
     bool isDescendantOrShadowDescendantOf(const Node*) const;
     WEBCORE_EXPORT bool contains(const Node*) const;
     bool containsIncludingShadowDOM(const Node*) const;
-    bool containsIncludingHostElements(const Node*) const;
 
     // Number of DOM 16-bit units contained in node. Note that rendered text length can be different - e.g. because of
     // css-transform:capitalize breaking up precomposed characters and ligatures.
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to