Modified: tags/Safari-602.1.18.0.4/Source/WebCore/ChangeLog (196450 => 196451)
--- tags/Safari-602.1.18.0.4/Source/WebCore/ChangeLog 2016-02-11 23:13:29 UTC (rev 196450)
+++ tags/Safari-602.1.18.0.4/Source/WebCore/ChangeLog 2016-02-11 23:17:19 UTC (rev 196451)
@@ -1,3 +1,24 @@
+2016-02-11 Babak Shafiei <[email protected]>
+
+ Merge r196445.
+
+ 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-09 Babak Shafiei <[email protected]>
Merge r195975.
Modified: tags/Safari-602.1.18.0.4/Source/WebCore/editing/cocoa/DataDetection.mm (196450 => 196451)
--- tags/Safari-602.1.18.0.4/Source/WebCore/editing/cocoa/DataDetection.mm 2016-02-11 23:13:29 UTC (rev 196450)
+++ tags/Safari-602.1.18.0.4/Source/WebCore/editing/cocoa/DataDetection.mm 2016-02-11 23:17:19 UTC (rev 196451)
@@ -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) {