Title: [247180] trunk
Revision
247180
Author
rn...@webkit.org
Date
2019-07-05 14:56:58 -0700 (Fri, 05 Jul 2019)

Log Message

[iOS] Crash in WebKit::WebPage::positionInformation via Range::startPosition
https://bugs.webkit.org/show_bug.cgi?id=199503

Reviewed by Wenson Hsieh.

Source/WebCore:

* editing/Editor.cpp:
(WebCore::Editor::compositionRange const): Added a FIXME.

Source/WebKit:

The crash was caused because focusedElementPositionInformation asssumes Editor::compositionRange is not null
whenever Editor::hasComposition returns true, which is not necessary the case when Editor::m_compositionNode
contains no text (data is of length 0).

Fixed the crash by adding an early return for when Editor::compositionRange returns nullptr.

* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::focusedElementPositionInformation):

Tools:

Added UIScriptController.ensurePositionInformationIsUpToDateAt using the existing WKWebView SPI:
_requestActivatedElementAtPosition

* DumpRenderTree/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptController::ensurePositionInformationIsUpToDateAt):
* DumpRenderTree/mac/UIScriptControllerMac.mm:
(WTR::UIScriptController::ensurePositionInformationIsUpToDateAt):
* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.cpp:
(WTR::UIScriptController::ensurePositionInformationIsUpToDateAt):
* TestRunnerShared/UIScriptContext/UIScriptController.h:
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptController::ensurePositionInformationIsUpToDateAt):
* WebKitTestRunner/ios/UIScriptControllerMac.mm:
(WTR::UIScriptController::ensurePositionInformationIsUpToDateAt):

LayoutTests:

Added a regression test for the crash.

* editing/input/delete-text-in-composition-expected.txt: Added.
* editing/input/delete-text-in-composition.html: Added.
* resources/ui-helper.js:
(window.UIHelper.ensurePositionInformationUpdateForElement): Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (247179 => 247180)


--- trunk/LayoutTests/ChangeLog	2019-07-05 21:48:54 UTC (rev 247179)
+++ trunk/LayoutTests/ChangeLog	2019-07-05 21:56:58 UTC (rev 247180)
@@ -1,3 +1,17 @@
+2019-07-05  Ryosuke Niwa  <rn...@webkit.org>
+
+        [iOS] Crash in WebKit::WebPage::positionInformation via Range::startPosition
+        https://bugs.webkit.org/show_bug.cgi?id=199503
+
+        Reviewed by Wenson Hsieh.
+
+        Added a regression test for the crash.
+
+        * editing/input/delete-text-in-composition-expected.txt: Added.
+        * editing/input/delete-text-in-composition.html: Added.
+        * resources/ui-helper.js:
+        (window.UIHelper.ensurePositionInformationUpdateForElement): Added.
+
 2019-07-02  Myles C. Maxfield  <mmaxfi...@apple.com>
 
         [WHLSL] Standard library is too big to directly include in WebCore

Added: trunk/LayoutTests/editing/input/delete-text-in-composition-expected.txt (0 => 247180)


--- trunk/LayoutTests/editing/input/delete-text-in-composition-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/editing/input/delete-text-in-composition-expected.txt	2019-07-05 21:56:58 UTC (rev 247180)
@@ -0,0 +1,7 @@
+PASS successfullyParsed is true
+
+TEST COMPLETE
+This tests deleting the composition text does not result in a crash.
+To manually test, type in the box below using input method (e.g. Japanese or Chinese). WebKit on iOS should not crash.
+
+PASS - WebKit did not crash

Added: trunk/LayoutTests/editing/input/delete-text-in-composition.html (0 => 247180)


--- trunk/LayoutTests/editing/input/delete-text-in-composition.html	                        (rev 0)
+++ trunk/LayoutTests/editing/input/delete-text-in-composition.html	2019-07-05 21:56:58 UTC (rev 247180)
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<body>
+<p>This tests deleting the composition text does not result in a crash.<br>
+To manually test, type in the box below using input method (e.g. Japanese or Chinese). WebKit on iOS should not crash.</p>
+<div id="editor" style="border: solid 2px blue; padding: 5px;" contenteditable></div>
+<div id="result"></div>
+<script src=""
+<script src=""
+<script>
+
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+
+editor.focus();
+
+async function runTest() {
+    if (window.textInputController) {
+        textInputController.setMarkedText("hello", 0, 5);
+        await UIHelper.ensurePresentationUpdate();
+        editor.firstChild.data = '';
+        await UIHelper.ensurePositionInformationUpdateForElement(editor);
+        result.textContent = 'PASS - WebKit did not crash';
+    }
+    testRunner.notifyDone();
+}
+
+window._onload_ = runTest;
+
+var successfullyParsed = true;
+
+</script>
+</body>
+</html>

Modified: trunk/LayoutTests/resources/ui-helper.js (247179 => 247180)


--- trunk/LayoutTests/resources/ui-helper.js	2019-07-05 21:48:54 UTC (rev 247179)
+++ trunk/LayoutTests/resources/ui-helper.js	2019-07-05 21:56:58 UTC (rev 247180)
@@ -254,6 +254,25 @@
         });
     }
 
+    static ensurePositionInformationUpdateForElement(element)
+    {
+        const boundingRect = element.getBoundingClientRect();
+        const x = boundingRect.x + 5;
+        const y = boundingRect.y + 5;
+
+        if (!this.isWebKit2()) {
+            testRunner.display();
+            return Promise.resolve();
+        }
+
+        return new Promise(resolve => {
+            testRunner.runUIScript(`
+                uiController.ensurePositionInformationIsUpToDateAt(${x}, ${y}, function () {
+                    uiController.uiScriptComplete();
+                });`, resolve);
+        });
+    }
+
     static delayFor(ms)
     {
         return new Promise(resolve => setTimeout(resolve, ms));

Modified: trunk/Source/WebCore/ChangeLog (247179 => 247180)


--- trunk/Source/WebCore/ChangeLog	2019-07-05 21:48:54 UTC (rev 247179)
+++ trunk/Source/WebCore/ChangeLog	2019-07-05 21:56:58 UTC (rev 247180)
@@ -1,3 +1,13 @@
+2019-07-05  Ryosuke Niwa  <rn...@webkit.org>
+
+        [iOS] Crash in WebKit::WebPage::positionInformation via Range::startPosition
+        https://bugs.webkit.org/show_bug.cgi?id=199503
+
+        Reviewed by Wenson Hsieh.
+
+        * editing/Editor.cpp:
+        (WebCore::Editor::compositionRange const): Added a FIXME.
+
 2019-07-02  Myles C. Maxfield  <mmaxfi...@apple.com>
 
         [WHLSL] Standard library is too big to directly include in WebCore

Modified: trunk/Source/WebCore/editing/Editor.cpp (247179 => 247180)


--- trunk/Source/WebCore/editing/Editor.cpp	2019-07-05 21:48:54 UTC (rev 247179)
+++ trunk/Source/WebCore/editing/Editor.cpp	2019-07-05 21:56:58 UTC (rev 247180)
@@ -3077,6 +3077,7 @@
     unsigned length = m_compositionNode->length();
     unsigned start = std::min(m_compositionStart, length);
     unsigned end = std::min(std::max(start, m_compositionEnd), length);
+    // FIXME: Why is this early return neeed?
     if (start >= end)
         return nullptr;
     return Range::create(m_compositionNode->document(), m_compositionNode.get(), start, m_compositionNode.get(), end);

Modified: trunk/Source/WebKit/ChangeLog (247179 => 247180)


--- trunk/Source/WebKit/ChangeLog	2019-07-05 21:48:54 UTC (rev 247179)
+++ trunk/Source/WebKit/ChangeLog	2019-07-05 21:56:58 UTC (rev 247180)
@@ -1,3 +1,19 @@
+2019-07-05  Ryosuke Niwa  <rn...@webkit.org>
+
+        [iOS] Crash in WebKit::WebPage::positionInformation via Range::startPosition
+        https://bugs.webkit.org/show_bug.cgi?id=199503
+
+        Reviewed by Wenson Hsieh.
+
+        The crash was caused because focusedElementPositionInformation asssumes Editor::compositionRange is not null
+        whenever Editor::hasComposition returns true, which is not necessary the case when Editor::m_compositionNode
+        contains no text (data is of length 0).
+
+        Fixed the crash by adding an early return for when Editor::compositionRange returns nullptr.
+
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::focusedElementPositionInformation):
+
 2019-07-05  Zalan Bujtas  <za...@apple.com>
 
         [ContentChangeObserver] REGRESSION (r247015): facebook photo/video upload button is unresponsive to user interaction.

Modified: trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (247179 => 247180)


--- trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm	2019-07-05 21:48:54 UTC (rev 247179)
+++ trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm	2019-07-05 21:56:58 UTC (rev 247180)
@@ -2508,6 +2508,9 @@
     VisiblePosition position = frame.visiblePositionForPoint(constrainedPoint);
 
     RefPtr<Range> compositionRange = frame.editor().compositionRange();
+    if (!compositionRange)
+        return;
+
     if (position < compositionRange->startPosition())
         position = compositionRange->startPosition();
     else if (position > compositionRange->endPosition())

Modified: trunk/Tools/ChangeLog (247179 => 247180)


--- trunk/Tools/ChangeLog	2019-07-05 21:48:54 UTC (rev 247179)
+++ trunk/Tools/ChangeLog	2019-07-05 21:56:58 UTC (rev 247180)
@@ -1,3 +1,26 @@
+2019-07-05  Ryosuke Niwa  <rn...@webkit.org>
+
+        [iOS] Crash in WebKit::WebPage::positionInformation via Range::startPosition
+        https://bugs.webkit.org/show_bug.cgi?id=199503
+
+        Reviewed by Wenson Hsieh.
+
+        Added UIScriptController.ensurePositionInformationIsUpToDateAt using the existing WKWebView SPI:
+        _requestActivatedElementAtPosition
+
+        * DumpRenderTree/ios/UIScriptControllerIOS.mm:
+        (WTR::UIScriptController::ensurePositionInformationIsUpToDateAt):
+        * DumpRenderTree/mac/UIScriptControllerMac.mm:
+        (WTR::UIScriptController::ensurePositionInformationIsUpToDateAt):
+        * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
+        * TestRunnerShared/UIScriptContext/UIScriptController.cpp:
+        (WTR::UIScriptController::ensurePositionInformationIsUpToDateAt):
+        * TestRunnerShared/UIScriptContext/UIScriptController.h:
+        * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
+        (WTR::UIScriptController::ensurePositionInformationIsUpToDateAt):
+        * WebKitTestRunner/ios/UIScriptControllerMac.mm:
+        (WTR::UIScriptController::ensurePositionInformationIsUpToDateAt):
+
 2019-07-05  Ryan Haddad  <ryanhad...@apple.com>
 
         Unreviewed, rolling out r247115.

Modified: trunk/Tools/DumpRenderTree/ios/UIScriptControllerIOS.mm (247179 => 247180)


--- trunk/Tools/DumpRenderTree/ios/UIScriptControllerIOS.mm	2019-07-05 21:48:54 UTC (rev 247179)
+++ trunk/Tools/DumpRenderTree/ios/UIScriptControllerIOS.mm	2019-07-05 21:56:58 UTC (rev 247180)
@@ -63,6 +63,11 @@
     doAsyncTask(callback);
 }
 
+void UIScriptController::ensurePositionInformationIsUpToDateAt(long x, long y, JSValueRef callback)
+{
+    return doAsyncTask(callback);
+}
+
 void UIScriptController::doAfterVisibleContentRectUpdate(JSValueRef callback)
 {
     doAsyncTask(callback);

Modified: trunk/Tools/DumpRenderTree/mac/UIScriptControllerMac.mm (247179 => 247180)


--- trunk/Tools/DumpRenderTree/mac/UIScriptControllerMac.mm	2019-07-05 21:48:54 UTC (rev 247179)
+++ trunk/Tools/DumpRenderTree/mac/UIScriptControllerMac.mm	2019-07-05 21:56:58 UTC (rev 247180)
@@ -61,6 +61,11 @@
     doAsyncTask(callback);
 }
 
+void UIScriptController::ensurePositionInformationIsUpToDateAt(long x, long y, JSValueRef callback)
+{
+    doAsyncTask(callback);
+}
+
 void UIScriptController::doAfterVisibleContentRectUpdate(JSValueRef callback)
 {
     doAsyncTask(callback);

Modified: trunk/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl (247179 => 247180)


--- trunk/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl	2019-07-05 21:48:54 UTC (rev 247179)
+++ trunk/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl	2019-07-05 21:56:58 UTC (rev 247180)
@@ -45,7 +45,7 @@
 
     void doAfterPresentationUpdate(object callback); // Call the callback after sending a message to the WebProcess and receiving a subsequent update.
     void doAfterNextStablePresentationUpdate(object callback);
-
+    void ensurePositionInformationIsUpToDateAt(long x, long y, object callback);
     void doAfterVisibleContentRectUpdate(object callback);
 
     void simulateAccessibilitySettingsChangeNotification(object callback);

Modified: trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp (247179 => 247180)


--- trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp	2019-07-05 21:48:54 UTC (rev 247179)
+++ trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp	2019-07-05 21:56:58 UTC (rev 247180)
@@ -101,6 +101,10 @@
 {
 }
 
+void UIScriptController::ensurePositionInformationIsUpToDateAt(long x, long y, JSValueRef)
+{
+}
+
 void UIScriptController::doAfterVisibleContentRectUpdate(JSValueRef)
 {
 }

Modified: trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h (247179 => 247180)


--- trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h	2019-07-05 21:48:54 UTC (rev 247179)
+++ trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h	2019-07-05 21:56:58 UTC (rev 247180)
@@ -67,6 +67,7 @@
     void doAsyncTask(JSValueRef callback);
     void doAfterPresentationUpdate(JSValueRef callback);
     void doAfterNextStablePresentationUpdate(JSValueRef callback);
+    void ensurePositionInformationIsUpToDateAt(long x, long y, JSValueRef callback);
     void doAfterVisibleContentRectUpdate(JSValueRef callback);
 
     void zoomToScale(double scale, JSValueRef callback);

Modified: trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm (247179 => 247180)


--- trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm	2019-07-05 21:48:54 UTC (rev 247179)
+++ trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm	2019-07-05 21:56:58 UTC (rev 247180)
@@ -157,6 +157,18 @@
     }];
 }
 
+void UIScriptController::ensurePositionInformationIsUpToDateAt(long x, long y, JSValueRef callback)
+{
+    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
+
+    unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
+    [webView _requestActivatedElementAtPosition:CGPointMake(x, y) completionBlock:^(_WKActivatedElementInfo *) {
+        if (!m_context)
+            return;
+        m_context->asyncTaskComplete(callbackID);
+    }];
+}
+
 void UIScriptController::doAfterVisibleContentRectUpdate(JSValueRef callback)
 {
     TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();

Modified: trunk/Tools/WebKitTestRunner/mac/UIScriptControllerMac.mm (247179 => 247180)


--- trunk/Tools/WebKitTestRunner/mac/UIScriptControllerMac.mm	2019-07-05 21:48:54 UTC (rev 247179)
+++ trunk/Tools/WebKitTestRunner/mac/UIScriptControllerMac.mm	2019-07-05 21:56:58 UTC (rev 247180)
@@ -59,6 +59,11 @@
     doAsyncTask(callback);
 }
 
+void UIScriptController::ensurePositionInformationIsUpToDateAt(long, long, JSValueRef callback)
+{
+    doAsyncTask(callback);
+}
+
 void UIScriptController::doAfterVisibleContentRectUpdate(JSValueRef callback)
 {
     doAsyncTask(callback);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to