Crash in WebCore::Range::borderAndTextRects
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 20 Jun 2020 00:16:12 +0000 (00:16 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 20 Jun 2020 00:16:12 +0000 (00:16 +0000)
https://bugs.webkit.org/show_bug.cgi?id=209379

Patch by Pinki Gyanchandani <pgyanchandani@apple.com> on 2020-06-19
Reviewed by Darin Adler.

When a parentless node is moved to a new document, then all ranges associated with this node and its children also should
be updated with new document information.

Test woould be submitted later.

* dom/Document.cpp:
(WebCore::Document::parentlessNodeMoveToNewDocument):
* dom/Document.h:
* dom/Node.cpp:
(WebCore::Node::moveNodeToNewDocument):
* dom/Range.cpp:
(WebCore::Range::parentlessNodeMoveToNewDocumentAffectsRange):
(WebCore::Range::updateRangeForParentlessNodeMoveToNewDocument):
* dom/Range.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@263302 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/fast/dom/move-detached-child-in-range-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/dom/Node.cpp
Source/WebCore/dom/Range.cpp
Source/WebCore/dom/Range.h

index 03e0c28..b95d452 100644 (file)
@@ -1 +1 @@
-Final end container, offset: [object HTMLHeadingElement], 1
+Final end container, offset: [object HTMLHeadingElement], 0
index c143a21..026f916 100644 (file)
@@ -1,3 +1,25 @@
+2020-06-19  Pinki Gyanchandani  <pgyanchandani@apple.com>
+
+        Crash in WebCore::Range::borderAndTextRects
+        https://bugs.webkit.org/show_bug.cgi?id=209379
+
+        Reviewed by Darin Adler.
+
+        When a parentless node is moved to a new document, then all ranges associated with this node and its children also should
+        be updated with new document information.
+
+        Test woould be submitted later. 
+
+        * dom/Document.cpp:
+        (WebCore::Document::parentlessNodeMoveToNewDocument):
+        * dom/Document.h:
+        * dom/Node.cpp:
+        (WebCore::Node::moveNodeToNewDocument):
+        * dom/Range.cpp:
+        (WebCore::Range::parentlessNodeMoveToNewDocumentAffectsRange):
+        (WebCore::Range::updateRangeForParentlessNodeMoveToNewDocument):
+        * dom/Range.h:
+
 2020-06-19  Truitt Savell  <tsavell@apple.com>
 
         Unreviewed, reverting r263121.
index 9f1e823..cac529c 100644 (file)
@@ -4675,6 +4675,19 @@ void Document::nodeWillBeRemoved(Node& node)
         m_markers->removeMarkers(node);
 }
 
+void Document::parentlessNodeMovedToNewDocument(Node& node)
+{
+    Vector<Range*, 5> rangesAffected;
+
+    for (auto* range : m_ranges) {
+        if (range->parentlessNodeMovedToNewDocumentAffectsRange(node))
+            rangesAffected.append(range);
+    }
+
+    for (auto* range : rangesAffected)
+        range->updateRangeForParentlessNodeMovedToNewDocument(node);
+}
+
 static Node* fallbackFocusNavigationStartingNodeAfterRemoval(Node& node)
 {
     return node.previousSibling() ? node.previousSibling() : node.parentNode();
index 6f7d2c0..324cace 100644 (file)
@@ -829,6 +829,7 @@ public:
     void nodeChildrenWillBeRemoved(ContainerNode&);
     // nodeWillBeRemoved is only safe when removing one node at a time.
     void nodeWillBeRemoved(Node&);
+    void parentlessNodeMovedToNewDocument(Node&);
 
     enum class AcceptChildOperation { Replace, InsertOrAdd };
     bool canAcceptChild(const Node& newChild, const Node* refChild, AcceptChildOperation) const;
index a4a03c8..6fa07c7 100644 (file)
@@ -2059,6 +2059,9 @@ void Node::moveNodeToNewDocument(Document& oldDocument, Document& newDocument)
 
     oldDocument.moveNodeIteratorsToNewDocument(*this, newDocument);
 
+    if (!parentNode())
+        oldDocument.parentlessNodeMovedToNewDocument(*this);
+
     if (AXObjectCache::accessibilityEnabled()) {
         if (auto* cache = oldDocument.existingAXObjectCache())
             cache->remove(*this);
index d5bde0a..7b0c042 100644 (file)
@@ -1612,6 +1612,18 @@ void Range::nodeWillBeRemoved(Node& node)
     boundaryNodeWillBeRemoved(m_end, node);
 }
 
+bool Range::parentlessNodeMovedToNewDocumentAffectsRange(Node& node)
+{
+    return node.containsIncludingShadowDOM(m_start.container());
+}
+
+void Range::updateRangeForParentlessNodeMovedToNewDocument(Node& node)
+{
+    m_ownerDocument->detachRange(*this);
+    m_ownerDocument = node.document();
+    m_ownerDocument->attachRange(*this);
+}
+
 static inline void boundaryTextInserted(RangeBoundaryPoint& boundary, Node& text, unsigned offset, unsigned length)
 {
     if (boundary.container() != &text)
index 8a26ab5..ace9873 100644 (file)
@@ -127,6 +127,8 @@ public:
     void nodeChildrenChanged(ContainerNode&);
     void nodeChildrenWillBeRemoved(ContainerNode&);
     void nodeWillBeRemoved(Node&);
+    bool parentlessNodeMovedToNewDocumentAffectsRange(Node&);
+    void updateRangeForParentlessNodeMovedToNewDocument(Node&);
 
     void textInserted(Node&, unsigned offset, unsigned length);
     void textRemoved(Node&, unsigned offset, unsigned length);