Title: [212721] branches/safari-603-branch

Diff

Modified: branches/safari-603-branch/LayoutTests/ChangeLog (212720 => 212721)


--- branches/safari-603-branch/LayoutTests/ChangeLog	2017-02-21 18:21:22 UTC (rev 212720)
+++ branches/safari-603-branch/LayoutTests/ChangeLog	2017-02-21 18:21:28 UTC (rev 212721)
@@ -1,3 +1,20 @@
+2017-02-18  Ryosuke Niwa  <[email protected]>
+
+        REGRESSION(r212218): Assertion failures in and after parserRemoveChild
+        https://bugs.webkit.org/show_bug.cgi?id=168458
+
+        Reviewed by Antti Koivisto.
+
+        Add tests to make sure parserAppendChild aren't called when a node removed by parserRemoveChild
+        had already been been inserted elsewhere by scripts.
+
+        * fast/parser/adoption-agency-unload-iframe-3-expected.txt: Added.
+        * fast/parser/adoption-agency-unload-iframe-3.html: Added.
+        * fast/parser/adoption-agency-unload-iframe-4-expected.txt: Added.
+        * fast/parser/adoption-agency-unload-iframe-4.html: Added.
+        * fast/parser/xml-error-unload-iframe-expected.txt: Added.
+        * fast/parser/xml-error-unload-iframe.html: Added.
+
 2017-02-20  Matthew Hanson  <[email protected]>
 
         Rollout r212647. rdar://problem/30563318

Added: branches/safari-603-branch/LayoutTests/fast/parser/adoption-agency-unload-iframe-3-expected.txt (0 => 212721)


--- branches/safari-603-branch/LayoutTests/fast/parser/adoption-agency-unload-iframe-3-expected.txt	                        (rev 0)
+++ branches/safari-603-branch/LayoutTests/fast/parser/adoption-agency-unload-iframe-3-expected.txt	2017-02-21 18:21:28 UTC (rev 212721)
@@ -0,0 +1,3 @@
+
+PASS An element removed by the adoption agency algorithm must not be inserted if it had been inserted elsewhere 
+

Added: branches/safari-603-branch/LayoutTests/fast/parser/adoption-agency-unload-iframe-3.html (0 => 212721)


--- branches/safari-603-branch/LayoutTests/fast/parser/adoption-agency-unload-iframe-3.html	                        (rev 0)
+++ branches/safari-603-branch/LayoutTests/fast/parser/adoption-agency-unload-iframe-3.html	2017-02-21 18:21:28 UTC (rev 212721)
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<head>
+<script src=""
+<script src=""
+<script>
+
+function runTest() {
+    const section = document.querySelector('section');
+    const container = document.querySelector('div');
+    const p = document.querySelector('p');
+    const iframe = document.createElement('iframe');
+    document.querySelector('b').appendChild(iframe);
+    /* div
+         + b
+           + p
+             + script
+             + iframe */
+    iframe.contentWindow._onunload_ = () => {
+        section.appendChild(p);
+        container.remove();
+        /* body
+           + p
+             + script
+             + iframe  */
+    }
+
+    window._onload_ = () => {
+        let test = async_test('An element removed by the adoption agency algorithm must not be inserted if it had been inserted elsewhere');
+        test.step(() => {
+            assert_not_equals(p.parentNode, container);
+            assert_equals(p.parentNode, section);
+        });
+        test.done();
+    }
+}
+
+</script>
+</head>
+<body>
+<section><div><b><p><script>runTest();</script></b></p></div></section>
+</body>

Added: branches/safari-603-branch/LayoutTests/fast/parser/adoption-agency-unload-iframe-4-expected.txt (0 => 212721)


--- branches/safari-603-branch/LayoutTests/fast/parser/adoption-agency-unload-iframe-4-expected.txt	                        (rev 0)
+++ branches/safari-603-branch/LayoutTests/fast/parser/adoption-agency-unload-iframe-4-expected.txt	2017-02-21 18:21:28 UTC (rev 212721)
@@ -0,0 +1,3 @@
+
+PASS An element removed by the adoption agency algorithm must not be inserted if it had been inserted elsewhere 
+

Added: branches/safari-603-branch/LayoutTests/fast/parser/adoption-agency-unload-iframe-4.html (0 => 212721)


--- branches/safari-603-branch/LayoutTests/fast/parser/adoption-agency-unload-iframe-4.html	                        (rev 0)
+++ branches/safari-603-branch/LayoutTests/fast/parser/adoption-agency-unload-iframe-4.html	2017-02-21 18:21:28 UTC (rev 212721)
@@ -0,0 +1,47 @@
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<script>
+
+let test = async_test('An element removed by the adoption agency algorithm must not be inserted if it had been inserted elsewhere');
+
+var p;
+test.step(() => {
+    const iframe = document.createElement('iframe');
+    document.body.appendChild(iframe);
+
+    let doc = iframe.contentDocument;
+    doc.write(`<body><a id="target" href=""
+
+    const target = doc.querySelector('a');
+    target._onfocus_ = () => {
+        target._onfocus_ = null;
+
+        test.step(() => {
+            let container = doc.querySelector('div');
+            container.remove();
+            doc.body.appendChild(p);
+        });
+
+        setTimeout(() => {
+            test.step(() => {
+                assert_equals(p.parentNode, doc.body);
+            });
+            test.done();
+            iframe.remove();
+        }, 0);
+    }
+
+    doc.write(`<div><b><p><script>
+        parent.p = document.querySelector('p');
+        document.write('<link rel="stylesheet" href=""
+        location.hash = 'target';
+    <\/script></b></p></div></body>`);
+});
+
+</script>
+</body>
+</html>

Added: branches/safari-603-branch/LayoutTests/fast/parser/xml-error-unload-iframe-expected.txt (0 => 212721)


--- branches/safari-603-branch/LayoutTests/fast/parser/xml-error-unload-iframe-expected.txt	                        (rev 0)
+++ branches/safari-603-branch/LayoutTests/fast/parser/xml-error-unload-iframe-expected.txt	2017-02-21 18:21:28 UTC (rev 212721)
@@ -0,0 +1,3 @@
+
+PASS An element removed by the adoption agency algorithm must not be inserted if it had been inserted elsewhere 
+

Added: branches/safari-603-branch/LayoutTests/fast/parser/xml-error-unload-iframe.html (0 => 212721)


--- branches/safari-603-branch/LayoutTests/fast/parser/xml-error-unload-iframe.html	                        (rev 0)
+++ branches/safari-603-branch/LayoutTests/fast/parser/xml-error-unload-iframe.html	2017-02-21 18:21:28 UTC (rev 212721)
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<script>
+
+let svgElement;
+function moveIframe(svgDoc) {
+    if (svgElement)
+        return;
+    svgElement = svgDoc.documentElement;
+    const iframe = document.createElement('iframe');
+    svgDoc.documentElement.appendChild(iframe);
+    iframe.contentWindow._onunload_ = () => {
+        document.body.appendChild(svgElement);
+    }
+}
+
+const content = `<svg xmlns="http://www.w3.org/2000/svg"><script>parent.moveIframe(document);<\/script><element a="1" a="2"/></svg>`;
+const iframe = document.createElement('iframe');
+iframe.src = "" Blob([content], {type: 'text/xml'}));
+document.documentElement.appendChild(iframe);
+
+window._onload_ = () => {
+    let test = async_test('An element removed by the adoption agency algorithm must not be inserted if it had been inserted elsewhere');
+    test.step(() => {
+        assert_equals(svgElement.parentNode, document.body);
+        svgElement.remove();
+    });
+    test.done();
+}
+
+</script>
+</body>

Modified: branches/safari-603-branch/Source/WebCore/ChangeLog (212720 => 212721)


--- branches/safari-603-branch/Source/WebCore/ChangeLog	2017-02-21 18:21:22 UTC (rev 212720)
+++ branches/safari-603-branch/Source/WebCore/ChangeLog	2017-02-21 18:21:28 UTC (rev 212721)
@@ -1,3 +1,39 @@
+2017-02-18  Ryosuke Niwa  <[email protected]>
+
+        REGRESSION(r212218): Assertion failures in and after parserRemoveChild
+        https://bugs.webkit.org/show_bug.cgi?id=168458
+
+        Reviewed by Antti Koivisto.
+
+        The bug was caused by parserRemoveChild not preceeding to remove oldChild even when
+        oldChild had been inserted elsewhere during unload evnets of the disconnected frames.
+        Fixed the bug by checking this condition and exiting early.
+
+        Also fixed various callers of parserRemoveChild to not call parserAppendChild when
+        the removed node had already been inserted elsewhere by scripts.
+
+        Tests: fast/parser/adoption-agency-unload-iframe-3.html
+               fast/parser/adoption-agency-unload-iframe-4.html
+               fast/parser/xml-error-unload-iframe.html
+
+        * dom/ContainerNode.cpp:
+        (WebCore::ContainerNode::parserRemoveChild): Exit early when the node had been
+        inserted elsewhere while firing unload events. Also moved the call to
+        notifyRemovePendingSheetIfNeeded outside NoEventDispatchAssertion since it can
+        synchrnously fire a focus event.
+        (WebCore::ContainerNode::parserAppendChild): Moved adoptNode call to inside
+        NoEventDispatchAssertion since adoptNode call here should never mutate DOM.
+        * html/parser/HTMLConstructionSite.cpp:
+        (WebCore::executeReparentTask): Added an early exit when the node had already been
+        inserted elsewhere.
+        (WebCore::executeInsertAlreadyParsedChildTask): Ditto.
+        * xml/XMLErrors.cpp:
+        (WebCore::XMLErrors::insertErrorMessageBlock): Ditto.
+        * xml/parser/XMLDocumentParser.cpp:
+        (WebCore::XMLDocumentParser::end): Fixed a crash unveiled by one of the test cases.
+        Exit early when insertErrorMessageBlock detached the parser (by author scripts).
+        (WebCore::XMLDocumentParser::finish): Keep the parser alive until we exit.
+
 2017-02-20  Ryosuke Niwa  <[email protected]>
 
         HTMLConstructionSiteTask::Insert should never be called on a node with a parent

Modified: branches/safari-603-branch/Source/WebCore/dom/ContainerNode.cpp (212720 => 212721)


--- branches/safari-603-branch/Source/WebCore/dom/ContainerNode.cpp	2017-02-21 18:21:22 UTC (rev 212720)
+++ branches/safari-603-branch/Source/WebCore/dom/ContainerNode.cpp	2017-02-21 18:21:28 UTC (rev 212721)
@@ -598,23 +598,27 @@
 void ContainerNode::parserRemoveChild(Node& oldChild)
 {
     disconnectSubframesIfNeeded(*this, DescendantsOnly);
+    if (oldChild.parentNode() != this)
+        return;
 
-    NoEventDispatchAssertion assertNoEventDispatch;
+    {
+        NoEventDispatchAssertion assertNoEventDispatch;
 
-    document().nodeChildrenWillBeRemoved(*this);
+        document().nodeChildrenWillBeRemoved(*this);
 
-    ASSERT(oldChild.parentNode() == this);
-    ASSERT(!oldChild.isDocumentFragment());
+        ASSERT(oldChild.parentNode() == this);
+        ASSERT(!oldChild.isDocumentFragment());
 
-    Node* prev = oldChild.previousSibling();
-    Node* next = oldChild.nextSibling();
+        Node* prev = oldChild.previousSibling();
+        Node* next = oldChild.nextSibling();
 
-    ChildListMutationScope(*this).willRemoveChild(oldChild);
-    oldChild.notifyMutationObserversNodeWillDetach();
+        ChildListMutationScope(*this).willRemoveChild(oldChild);
+        oldChild.notifyMutationObserversNodeWillDetach();
 
-    removeBetween(prev, next, oldChild);
+        removeBetween(prev, next, oldChild);
 
-    notifyChildRemoved(oldChild, prev, next, ChildChangeSourceParser);
+        notifyChildRemoved(oldChild, prev, next, ChildChangeSourceParser);
+    }
     document().notifyRemovePendingSheetIfNeeded();
 }
 
@@ -719,11 +723,12 @@
     ASSERT(!newChild.isDocumentFragment());
     ASSERT(!hasTagName(HTMLNames::templateTag));
 
-    if (&document() != &newChild.document())
-        document().adoptNode(newChild);
-
     {
         NoEventDispatchAssertion assertNoEventDispatch;
+
+        if (&document() != &newChild.document())
+            document().adoptNode(newChild);
+
         appendChildCommon(newChild);
         treeScope().adoptIfNeeded(newChild);
     }

Modified: branches/safari-603-branch/Source/WebCore/html/parser/HTMLConstructionSite.cpp (212720 => 212721)


--- branches/safari-603-branch/Source/WebCore/html/parser/HTMLConstructionSite.cpp	2017-02-21 18:21:22 UTC (rev 212720)
+++ branches/safari-603-branch/Source/WebCore/html/parser/HTMLConstructionSite.cpp	2017-02-21 18:21:28 UTC (rev 212721)
@@ -131,6 +131,9 @@
     if (auto* parent = task.child->parentNode())
         parent->parserRemoveChild(*task.child);
 
+    if (task.child->parentNode())
+        return;
+
     task.parent->parserAppendChild(*task.child);
 }
 
@@ -140,6 +143,10 @@
 
     if (ContainerNode* parent = task.child->parentNode())
         parent->parserRemoveChild(*task.child);
+
+    if (task.child->parentNode())
+        return;
+
     insert(task);
 }
 

Modified: branches/safari-603-branch/Source/WebCore/xml/XMLErrors.cpp (212720 => 212721)


--- branches/safari-603-branch/Source/WebCore/xml/XMLErrors.cpp	2017-02-21 18:21:22 UTC (rev 212720)
+++ branches/safari-603-branch/Source/WebCore/xml/XMLErrors.cpp	2017-02-21 18:21:28 UTC (rev 212721)
@@ -140,8 +140,9 @@
         rootElement->parserAppendChild(body);
 
         m_document.parserRemoveChild(*documentElement);
+        if (!documentElement->parentNode())
+            body->parserAppendChild(*documentElement);
 
-        body->parserAppendChild(*documentElement);
         m_document.parserAppendChild(rootElement);
 
         documentElement = WTFMove(body);

Modified: branches/safari-603-branch/Source/WebCore/xml/parser/XMLDocumentParser.cpp (212720 => 212721)


--- branches/safari-603-branch/Source/WebCore/xml/parser/XMLDocumentParser.cpp	2017-02-21 18:21:22 UTC (rev 212720)
+++ branches/safari-603-branch/Source/WebCore/xml/parser/XMLDocumentParser.cpp	2017-02-21 18:21:28 UTC (rev 212721)
@@ -195,9 +195,11 @@
     if (m_parserPaused)
         return;
 
-    if (m_sawError)
+    if (m_sawError) {
         insertErrorMessageBlock();
-    else {
+        if (isDetached()) // Inserting an error message may have ran arbitrary scripts.
+            return;
+    } else {
         updateLeafTextNode();
         document()->styleScope().didChangeStyleSheetEnvironment();
     }
@@ -215,6 +217,8 @@
     // makes sense to call any methods on DocumentParser once it's been stopped.
     // However, FrameLoader::stop calls DocumentParser::finish unconditionally.
 
+    Ref<XMLDocumentParser> protectedThis(*this);
+
     if (m_parserPaused)
         m_finishCalled = true;
     else
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to