Title: [281579] trunk
Revision
281579
Author
[email protected]
Date
2021-08-25 14:01:01 -0700 (Wed, 25 Aug 2021)

Log Message

[iOS] Crash when tapping <select> element and calling window.open()
https://bugs.webkit.org/show_bug.cgi?id=229468
rdar://82122972

Reviewed by Wenson Hsieh.

Source/WebKit:

UIKit throws an exception when attempting to present a context menu
for a view that is not in a window.

One instance where this can occur in Safari is when a call to
window.open() is made in response to a touch on a select element.
In this scenario, the call to window.open() opens a new tab, unparenting
the current webview. However, the touch also focuses the element, and
WebKit attempts to present a context menu in an unparented view.

To fix, guard against the case where the view is not parented, and do
not attempt to present a context menu.

Test: fast/forms/ios/show-select-menu-in-unparented-view-crash.html

* UIProcess/ios/WKActionSheetAssistant.mm:

Note that the helper method used in other classes is not used in
WKActionSheetAssistant, since the hosting view is not always a
WKContentView.

(-[WKActionSheetAssistant showDataDetectorsUIForPositionInformation:]):
(-[WKActionSheetAssistant showMediaControlsContextMenu:items:completionHandler:]):
* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView presentContextMenu:atLocation:]):

Added a helper method to ensure the view is parented prior to presenting
a context menu.

(-[WKContentView imageAnalysisGestureDidTimeOut:]):
* UIProcess/ios/WebDataListSuggestionsDropdownIOS.mm:
(-[WKDataListSuggestionsDropdown _showSuggestions]):
* UIProcess/ios/forms/WKDateTimeInputControl.mm:
(-[WKDateTimePicker showDateTimePicker]):
* UIProcess/ios/forms/WKFileUploadPanel.mm:
(-[WKFileUploadPanel showDocumentPickerMenu]):
* UIProcess/ios/forms/WKFormSelectPicker.mm:
(-[WKSelectPicker showSelectPicker]):

LayoutTests:

Added a test to verify a crash does not occur when tapping a <select>
element and unparenting the webview.

* fast/forms/ios/show-select-menu-in-unparented-view-crash-expected.txt: Added.
* fast/forms/ios/show-select-menu-in-unparented-view-crash.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (281578 => 281579)


--- trunk/LayoutTests/ChangeLog	2021-08-25 20:55:35 UTC (rev 281578)
+++ trunk/LayoutTests/ChangeLog	2021-08-25 21:01:01 UTC (rev 281579)
@@ -1,3 +1,17 @@
+2021-08-25  Aditya Keerthi  <[email protected]>
+
+        [iOS] Crash when tapping <select> element and calling window.open()
+        https://bugs.webkit.org/show_bug.cgi?id=229468
+        rdar://82122972
+
+        Reviewed by Wenson Hsieh.
+
+        Added a test to verify a crash does not occur when tapping a <select>
+        element and unparenting the webview.
+
+        * fast/forms/ios/show-select-menu-in-unparented-view-crash-expected.txt: Added.
+        * fast/forms/ios/show-select-menu-in-unparented-view-crash.html: Added.
+
 2021-08-25  Alan Bujtas  <[email protected]>
 
         Unreviewed test gardening after r228617.

Added: trunk/LayoutTests/fast/forms/ios/show-select-menu-in-unparented-view-crash-expected.txt (0 => 281579)


--- trunk/LayoutTests/fast/forms/ios/show-select-menu-in-unparented-view-crash-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/forms/ios/show-select-menu-in-unparented-view-crash-expected.txt	2021-08-25 21:01:01 UTC (rev 281579)
@@ -0,0 +1,9 @@
+This test verifies that tapping on a select element and then unparenting the webview does not result in a crash.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/forms/ios/show-select-menu-in-unparented-view-crash.html (0 => 281579)


--- trunk/LayoutTests/fast/forms/ios/show-select-menu-in-unparented-view-crash.html	                        (rev 0)
+++ trunk/LayoutTests/fast/forms/ios/show-select-menu-in-unparented-view-crash.html	2021-08-25 21:01:01 UTC (rev 281579)
@@ -0,0 +1,42 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+    <head>
+        <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
+        <script src=""
+        <script src=""
+    </head>
+<body>
+<select id="select">
+    <option>January</option>
+    <option>February</option>
+    <option>March</option>
+    <option>April</option>
+    <option>May</option>
+    <option>June</option>
+    <option>July</option>
+    <option>August</option>
+    <option>September</option>
+    <option>October</option>
+    <option>November</option>
+    <option>December</option>
+</select>
+</body>
+<script>
+jsTestIsAsync = true;
+
+addEventListener("load", async () => {
+    description("This test verifies that tapping on a select element and then unparenting the webview does not result in a crash.");
+
+    select.addEventListener("touchstart", () => {
+        UIHelper.removeViewFromWindow();
+    });
+
+    select.addEventListener("focus", async () => {
+        await UIHelper.ensurePresentationUpdate();
+        finishJSTest();
+    });
+
+    UIHelper.activateElement(select);
+});
+</script>
+</html>

Modified: trunk/Source/WebKit/ChangeLog (281578 => 281579)


--- trunk/Source/WebKit/ChangeLog	2021-08-25 20:55:35 UTC (rev 281578)
+++ trunk/Source/WebKit/ChangeLog	2021-08-25 21:01:01 UTC (rev 281579)
@@ -1,3 +1,50 @@
+2021-08-25  Aditya Keerthi  <[email protected]>
+
+        [iOS] Crash when tapping <select> element and calling window.open()
+        https://bugs.webkit.org/show_bug.cgi?id=229468
+        rdar://82122972
+
+        Reviewed by Wenson Hsieh.
+
+        UIKit throws an exception when attempting to present a context menu
+        for a view that is not in a window.
+
+        One instance where this can occur in Safari is when a call to
+        window.open() is made in response to a touch on a select element.
+        In this scenario, the call to window.open() opens a new tab, unparenting
+        the current webview. However, the touch also focuses the element, and
+        WebKit attempts to present a context menu in an unparented view.
+
+        To fix, guard against the case where the view is not parented, and do
+        not attempt to present a context menu.
+
+        Test: fast/forms/ios/show-select-menu-in-unparented-view-crash.html
+
+        * UIProcess/ios/WKActionSheetAssistant.mm:
+
+        Note that the helper method used in other classes is not used in
+        WKActionSheetAssistant, since the hosting view is not always a
+        WKContentView.
+
+        (-[WKActionSheetAssistant showDataDetectorsUIForPositionInformation:]):
+        (-[WKActionSheetAssistant showMediaControlsContextMenu:items:completionHandler:]):
+        * UIProcess/ios/WKContentViewInteraction.h:
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView presentContextMenu:atLocation:]):
+
+        Added a helper method to ensure the view is parented prior to presenting
+        a context menu.
+
+        (-[WKContentView imageAnalysisGestureDidTimeOut:]):
+        * UIProcess/ios/WebDataListSuggestionsDropdownIOS.mm:
+        (-[WKDataListSuggestionsDropdown _showSuggestions]):
+        * UIProcess/ios/forms/WKDateTimeInputControl.mm:
+        (-[WKDateTimePicker showDateTimePicker]):
+        * UIProcess/ios/forms/WKFileUploadPanel.mm:
+        (-[WKFileUploadPanel showDocumentPickerMenu]):
+        * UIProcess/ios/forms/WKFormSelectPicker.mm:
+        (-[WKSelectPicker showSelectPicker]):
+
 2021-08-25  Per Arne Vollan  <[email protected]>
 
         Build error preprocessing sandbox

Modified: trunk/Source/WebKit/UIProcess/ios/WKActionSheetAssistant.mm (281578 => 281579)


--- trunk/Source/WebKit/UIProcess/ios/WKActionSheetAssistant.mm	2021-08-25 20:55:35 UTC (rev 281578)
+++ trunk/Source/WebKit/UIProcess/ios/WKActionSheetAssistant.mm	2021-08-25 21:01:01 UTC (rev 281579)
@@ -770,7 +770,8 @@
         return;
     
 #if USE(UICONTEXTMENU) && HAVE(UICONTEXTMENU_LOCATION)
-    [self._ensureDataDetectorContextMenuInteraction _presentMenuAtLocation:_positionInformation->request.point];
+    if ([_view window])
+        [self._ensureDataDetectorContextMenuInteraction _presentMenuAtLocation:_positionInformation->request.point];
 #else
     NSMutableArray *elementActions = [NSMutableArray array];
     for (NSUInteger actionNumber = 0; actionNumber < [dataDetectorsActions count]; actionNumber++) {
@@ -831,7 +832,7 @@
         items = WTFMove(items[0].children);
     }
 
-    if (items.isEmpty()) {
+    if (![_view window] || items.isEmpty()) {
         completionHandler(WebCore::MediaControlsContextMenuItem::invalidID);
         return;
     }

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h (281578 => 281579)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h	2021-08-25 20:55:35 UTC (rev 281578)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h	2021-08-25 21:01:01 UTC (rev 281579)
@@ -730,6 +730,8 @@
 #if USE(UICONTEXTMENU)
 - (UIView *)textEffectsWindow;
 
+- (void)presentContextMenu:(UIContextMenuInteraction *)contextMenuInteraction atLocation:(CGPoint)location;
+
 - (UITargetedPreview *)_createTargetedContextMenuHintPreviewForFocusedElement;
 - (UITargetedPreview *)_createTargetedContextMenuHintPreviewIfPossible;
 - (void)_removeContextMenuHintContainerIfPossible;

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (281578 => 281579)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2021-08-25 20:55:35 UTC (rev 281578)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2021-08-25 21:01:01 UTC (rev 281579)
@@ -8761,6 +8761,14 @@
     [self _removeContainerForContextMenuHintPreviews];
 }
 
+- (void)presentContextMenu:(UIContextMenuInteraction *)contextMenuInteraction atLocation:(CGPoint) location
+{
+    if (!self.window)
+        return;
+
+    [contextMenuInteraction _presentMenuAtLocation:location];
+}
+
 #endif // USE(UICONTEXTMENU)
 
 #if HAVE(UI_WK_DOCUMENT_CONTEXT)
@@ -10453,7 +10461,7 @@
             [strongSelf _updateContextMenuForMachineReadableCodeForImageAnalysis:result];
 #endif // ENABLE(IMAGE_ANALYSIS_FOR_MACHINE_READABLE_CODES)
             strongSelf->_contextMenuWasTriggeredByImageAnalysisTimeout = YES;
-            [strongSelf->_contextMenuInteraction _presentMenuAtLocation:location];
+            [strongSelf presentContextMenu:strongSelf->_contextMenuInteraction.get() atLocation:location];
 #else
             UNUSED_PARAM(location);
 #endif // USE(UICONTEXTMENU)

Modified: trunk/Source/WebKit/UIProcess/ios/WebDataListSuggestionsDropdownIOS.mm (281578 => 281579)


--- trunk/Source/WebKit/UIProcess/ios/WebDataListSuggestionsDropdownIOS.mm	2021-08-25 20:55:35 UTC (rev 281578)
+++ trunk/Source/WebKit/UIProcess/ios/WebDataListSuggestionsDropdownIOS.mm	2021-08-25 21:01:01 UTC (rev 281579)
@@ -473,7 +473,8 @@
             if (!strongSelf)
                 return;
 
-            [strongSelf->_suggestionsContextMenuInteraction _presentMenuAtLocation:[[strongSelf view] lastInteractionLocation]];
+            auto view = [strongSelf view];
+            [view presentContextMenu:strongSelf->_suggestionsContextMenuInteraction.get() atLocation:[view lastInteractionLocation]];
         }];
     } else {
         [_suggestionsContextMenuInteraction updateVisibleMenuWithBlock:[&](UIMenu *visibleMenu) -> UIMenu * {

Modified: trunk/Source/WebKit/UIProcess/ios/forms/WKDateTimeInputControl.mm (281578 => 281579)


--- trunk/Source/WebKit/UIProcess/ios/forms/WKDateTimeInputControl.mm	2021-08-25 20:55:35 UTC (rev 281578)
+++ trunk/Source/WebKit/UIProcess/ios/forms/WKDateTimeInputControl.mm	2021-08-25 21:01:01 UTC (rev 281579)
@@ -511,7 +511,7 @@
     [_view.webView _didShowContextMenu];
 #elif USE(UICONTEXTMENU) && HAVE(UICONTEXTMENU_LOCATION)
     [self ensureContextMenuInteraction];
-    [_dateTimeContextMenuInteraction _presentMenuAtLocation:_interactionPoint];
+    [_view presentContextMenu:_dateTimeContextMenuInteraction.get() atLocation:_interactionPoint];
 #endif
 }
 

Modified: trunk/Source/WebKit/UIProcess/ios/forms/WKFileUploadPanel.mm (281578 => 281579)


--- trunk/Source/WebKit/UIProcess/ios/forms/WKFileUploadPanel.mm	2021-08-25 20:55:35 UTC (rev 281578)
+++ trunk/Source/WebKit/UIProcess/ios/forms/WKFileUploadPanel.mm	2021-08-25 21:01:01 UTC (rev 281579)
@@ -531,7 +531,7 @@
 #if HAVE(UICONTEXTMENU_LOCATION)
     if (_allowedImagePickerTypes.containsAny({ WKFileUploadPanelImagePickerType::Image, WKFileUploadPanelImagePickerType::Video })) {
         [self ensureContextMenuInteraction];
-        [_documentContextMenuInteraction _presentMenuAtLocation:_interactionPoint];
+        [_view presentContextMenu:_documentContextMenuInteraction.get() atLocation:_interactionPoint];
     } else // Image and Video types are not accepted so bypass the menu and open the file picker directly.
 #endif
         [self showFilePickerMenu];

Modified: trunk/Source/WebKit/UIProcess/ios/forms/WKFormSelectPicker.mm (281578 => 281579)


--- trunk/Source/WebKit/UIProcess/ios/forms/WKFormSelectPicker.mm	2021-08-25 20:55:35 UTC (rev 281578)
+++ trunk/Source/WebKit/UIProcess/ios/forms/WKFormSelectPicker.mm	2021-08-25 21:01:01 UTC (rev 281579)
@@ -717,7 +717,7 @@
 - (void)showSelectPicker
 {
     [self ensureContextMenuInteraction];
-    [_selectContextMenuInteraction _presentMenuAtLocation:_interactionPoint];
+    [_view presentContextMenu:_selectContextMenuInteraction.get() atLocation:_interactionPoint];
 }
 
 #endif // USE(UICONTEXTMENU)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to