[iOS DnD] Web content process crashes when the selection is moved far offscreen in...
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 30 Jun 2017 04:44:53 +0000 (04:44 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 30 Jun 2017 04:44:53 +0000 (04:44 +0000)
https://bugs.webkit.org/show_bug.cgi?id=174010
<rdar://problem/32597802>

Reviewed by Tim Horton.

Source/WebCore:

The TextIndicator snapshot generated in createDragImageForSelection is not guaranteed to succeed; this patch
adds a null check following TextIndicator::createWithSelectionInFrame and bails early if the snapshot was not
successful.

Test: DataInteractionTests.DoNotCrashWhenSelectionMovesOffscreenAfterDragStart

* platform/ios/DragImageIOS.mm:
(WebCore::createDragImageForSelection):

Tools:

Adds a new API test to ensure that we don't crash trying to dereference a null RefPtr when the TextIndicator
snapshot fails for any reason.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKit2Cocoa/dragstart-change-selection-offscreen.html: Added.
* TestWebKitAPI/Tests/ios/DataInteractionTests.mm:
(TestWebKitAPI::TEST):

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

Source/WebCore/ChangeLog
Source/WebCore/platform/ios/DragImageIOS.mm
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKit2Cocoa/dragstart-change-selection-offscreen.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/ios/DataInteractionTests.mm

index 159b8b8..c97e2b6 100644 (file)
@@ -1,3 +1,20 @@
+2017-06-29  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [iOS DnD] Web content process crashes when the selection is moved far offscreen in dragstart
+        https://bugs.webkit.org/show_bug.cgi?id=174010
+        <rdar://problem/32597802>
+
+        Reviewed by Tim Horton.
+
+        The TextIndicator snapshot generated in createDragImageForSelection is not guaranteed to succeed; this patch
+        adds a null check following TextIndicator::createWithSelectionInFrame and bails early if the snapshot was not
+        successful.
+
+        Test: DataInteractionTests.DoNotCrashWhenSelectionMovesOffscreenAfterDragStart
+
+        * platform/ios/DragImageIOS.mm:
+        (WebCore::createDragImageForSelection):
+
 2017-06-29  Chris Fleizach  <cfleizach@apple.com>
 
         AX: Cannot call setValue() on contenteditable or ARIA text controls
index 0207247..92d46e6 100644 (file)
@@ -184,6 +184,9 @@ DragImageRef createDragImageForSelection(Frame& frame, TextIndicatorData& indica
         options |= TextIndicatorOptionRespectTextColor;
 
     auto textIndicator = TextIndicator::createWithSelectionInFrame(frame, options, TextIndicatorPresentationTransition::None, FloatSize());
+    if (!textIndicator)
+        return nullptr;
+
     auto image = textIndicator->contentImage();
     if (image)
         indicatorData = textIndicator->data();
index d0bda50..49092e6 100644 (file)
@@ -1,3 +1,19 @@
+2017-06-29  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [iOS DnD] Web content process crashes when the selection is moved far offscreen in dragstart
+        https://bugs.webkit.org/show_bug.cgi?id=174010
+        <rdar://problem/32597802>
+
+        Reviewed by Tim Horton.
+
+        Adds a new API test to ensure that we don't crash trying to dereference a null RefPtr when the TextIndicator
+        snapshot fails for any reason.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKit2Cocoa/dragstart-change-selection-offscreen.html: Added.
+        * TestWebKitAPI/Tests/ios/DataInteractionTests.mm:
+        (TestWebKitAPI::TEST):
+
 2017-06-29  Chris Fleizach  <cfleizach@apple.com>
 
         AX: Cannot call setValue() on contenteditable or ARIA text controls
index 982790b..69bf47d 100644 (file)
                F46A095B1ED8A6E600D4AA55 /* gif-and-file-input.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F47D30ED1ED28A6C000482E1 /* gif-and-file-input.html */; };
                F47728991E4AE3C1007ABF6A /* full-page-contenteditable.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F47728981E4AE3AD007ABF6A /* full-page-contenteditable.html */; };
                F4856CA31E649EA8009D7EE7 /* attachment-element.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4856CA21E6498A8009D7EE7 /* attachment-element.html */; };
+               F4A32EC41F05F3850047C544 /* dragstart-change-selection-offscreen.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4A32EC31F05F3780047C544 /* dragstart-change-selection-offscreen.html */; };
                F4B825D81EF4DBFB006E417F /* compressed-files.zip in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4B825D61EF4DBD4006E417F /* compressed-files.zip */; };
                F4BFA68E1E4AD08000154298 /* DragAndDropPasteboardTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4BFA68C1E4AD08000154298 /* DragAndDropPasteboardTests.mm */; };
                F4C2AB221DD6D95E00E06D5B /* enormous-video-with-sound.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4C2AB211DD6D94100E06D5B /* enormous-video-with-sound.html */; };
                        dstPath = TestWebKitAPI.resources;
                        dstSubfolderSpec = 7;
                        files = (
+                               F4A32EC41F05F3850047C544 /* dragstart-change-selection-offscreen.html in Copy Resources */,
                                F469FB241F01804B00401539 /* contenteditable-and-target.html in Copy Resources */,
                                F4B825D81EF4DBFB006E417F /* compressed-files.zip in Copy Resources */,
                                F41AB99F1EF4696B0083FA08 /* autofocus-contenteditable.html in Copy Resources */,
                F47D30EB1ED28619000482E1 /* apple.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = apple.gif; sourceTree = "<group>"; };
                F47D30ED1ED28A6C000482E1 /* gif-and-file-input.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "gif-and-file-input.html"; sourceTree = "<group>"; };
                F4856CA21E6498A8009D7EE7 /* attachment-element.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "attachment-element.html"; sourceTree = "<group>"; };
+               F4A32EC31F05F3780047C544 /* dragstart-change-selection-offscreen.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "dragstart-change-selection-offscreen.html"; sourceTree = "<group>"; };
                F4B825D61EF4DBD4006E417F /* compressed-files.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = "compressed-files.zip"; sourceTree = "<group>"; };
                F4BFA68C1E4AD08000154298 /* DragAndDropPasteboardTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DragAndDropPasteboardTests.mm; sourceTree = "<group>"; };
                F4C2AB211DD6D94100E06D5B /* enormous-video-with-sound.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "enormous-video-with-sound.html"; sourceTree = "<group>"; };
                                F469FB231F01803500401539 /* contenteditable-and-target.html */,
                                F41AB99C1EF4692C0083FA08 /* contenteditable-and-textarea.html */,
                                F41AB99E1EF4692C0083FA08 /* div-and-large-image.html */,
+                               F4A32EC31F05F3780047C544 /* dragstart-change-selection-offscreen.html */,
                                F41AB99B1EF4692C0083FA08 /* file-uploading.html */,
                                F41AB9991EF4692C0083FA08 /* image-and-contenteditable.html */,
                                F41AB9931EF4692C0083FA08 /* image-and-textarea.html */,
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/dragstart-change-selection-offscreen.html b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/dragstart-change-selection-offscreen.html
new file mode 100644 (file)
index 0000000..640b521
--- /dev/null
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<style>
+body {
+    font-size: 200px;
+}
+
+#offscreen {
+    position: absolute;
+    top: -500vh;
+    left: -500vw;
+}
+</style>
+<div id="onscreen">DRAG ME</div>
+<div id="offscreen">FAR OFFSCREEN</div>
+<script>
+function selectChildNodesOfElement(element)
+{
+    let range = document.createRange();
+    range.setStartBefore(element.childNodes[0])
+    range.setEndAfter(element.childNodes[element.childNodes.length - 1]);
+    getSelection().removeAllRanges();
+    getSelection().addRange(range);
+}
+selectChildNodesOfElement(onscreen);
+document.body.addEventListener("dragstart", () => selectChildNodesOfElement(offscreen));
+</script>
+</html>
index 76fdb6b..15fa141 100644 (file)
@@ -1059,6 +1059,17 @@ TEST(DataInteractionTests, WebItemProviderPasteboardLoading)
     TestWebKitAPI::Util::run(&hasRunSecondCompletionBlock);
 }
 
+TEST(DataInteractionTests, DoNotCrashWhenSelectionMovesOffscreenAfterDragStart)
+{
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+    [webView synchronouslyLoadTestPageNamed:@"dragstart-change-selection-offscreen"];
+
+    auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
+    [simulator runFrom:CGPointMake(100, 100) to:CGPointMake(100, 100)];
+
+    EXPECT_WK_STREQ("FAR OFFSCREEN", [webView stringByEvaluatingJavaScript:@"getSelection().getRangeAt(0).toString()"]);
+}
+
 } // namespace TestWebKitAPI
 
 #endif // ENABLE(DATA_INTERACTION)