Title: [196445] trunk/Source/WebCore
Revision
196445
Author
[email protected]
Date
2016-02-11 15:04:13 -0800 (Thu, 11 Feb 2016)

Log Message

WebContent process crashes when performing data detection on content with existing data detector links.
https://bugs.webkit.org/show_bug.cgi?id=154118
rdar://problem/24511860

Reviewed by Tim Horton.

The DOM mutation caused by removing the existing links, can shift the range endpoints.
We now save the range enpoints as positions so that we can recreate the ranges,
if a DOM mutation occurred.

* editing/cocoa/DataDetection.mm:
(WebCore::removeResultLinksFromAnchor):
(WebCore::searchForLinkRemovingExistingDDLinks):
(WebCore::DataDetection::detectContentInRange):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (196444 => 196445)


--- trunk/Source/WebCore/ChangeLog	2016-02-11 23:01:39 UTC (rev 196444)
+++ trunk/Source/WebCore/ChangeLog	2016-02-11 23:04:13 UTC (rev 196445)
@@ -1,3 +1,20 @@
+2016-02-11  Enrica Casucci  <[email protected]>
+
+        WebContent process crashes when performing data detection on content with existing data detector links.
+        https://bugs.webkit.org/show_bug.cgi?id=154118
+        rdar://problem/24511860
+
+        Reviewed by Tim Horton.
+
+        The DOM mutation caused by removing the existing links, can shift the range endpoints.
+        We now save the range enpoints as positions so that we can recreate the ranges,
+        if a DOM mutation occurred.
+
+        * editing/cocoa/DataDetection.mm:
+        (WebCore::removeResultLinksFromAnchor):
+        (WebCore::searchForLinkRemovingExistingDDLinks):
+        (WebCore::DataDetection::detectContentInRange):
+
 2016-02-11  Jer Noble  <[email protected]>
 
         Make MediaResourceLoader behave more like a CachedResourceLoader.

Modified: trunk/Source/WebCore/editing/cocoa/DataDetection.mm (196444 => 196445)


--- trunk/Source/WebCore/editing/cocoa/DataDetection.mm	2016-02-11 23:01:39 UTC (rev 196444)
+++ trunk/Source/WebCore/editing/cocoa/DataDetection.mm	2016-02-11 23:04:13 UTC (rev 196445)
@@ -240,14 +240,16 @@
     }
 }
 
-static bool searchForLinkRemovingExistingDDLinks(Node* startNode, Node* endNode)
+static bool searchForLinkRemovingExistingDDLinks(Node* startNode, Node* endNode, bool &didModifyDOM)
 {
+    didModifyDOM = false;
     Node *node = startNode;
     while (node) {
         if (is<HTMLAnchorElement>(*node)) {
             if (downcast<Element>(*node).getAttribute(dataDetectorsURLScheme) != "true")
                 return true;
             removeResultLinksFromAnchor(node, node->parentElement());
+            didModifyDOM = true;
         }
         
         if (node == endNode) {
@@ -259,6 +261,7 @@
                     if (downcast<Element>(*node).getAttribute(dataDetectorsURLScheme) != "true")
                         return true;
                     removeResultLinksFromAnchor(node, node->parentElement());
+                    didModifyDOM = true;
                 }
                 node = node->parentNode();
             }
@@ -520,10 +523,25 @@
 
         NSString *identifier = dataDetectorStringForPath(indexPaths[resultIndex].get());
         NSString *correspondingURL = constructURLStringForResult(coreResult, identifier, referenceDate, (NSTimeZone *)tz, types);
+        bool didModifyDOM = false;
         
-        if (!correspondingURL || searchForLinkRemovingExistingDDLinks(&resultRanges.first()->startContainer(), &resultRanges.last()->endContainer()))
+        // Store the range boundaries as Position, because the DOM could change if we find
+        // old data detector link.
+        Vector<std::pair<Position, Position>> rangeBoundaries;
+        for (auto& range : resultRanges)
+            rangeBoundaries.append(std::make_pair(range->startPosition(), range->endPosition()));
+
+        if (!correspondingURL || searchForLinkRemovingExistingDDLinks(&resultRanges.first()->startContainer(), &resultRanges.last()->endContainer(), didModifyDOM))
             continue;
         
+        if (didModifyDOM) {
+            // If the DOM was modified because some old links were removed,
+            // we need to recreate the ranges because they could no longer be valid.
+            resultRanges.clear();
+            for (auto& rangeBoundary : rangeBoundaries)
+                resultRanges.append(Range::create(*rangeBoundary.first.document(), rangeBoundary.first, rangeBoundary.second));
+        }
+        
         lastModifiedQueryOffset = queryRange.end;
 
         for (auto& range : resultRanges) {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to