Changeset 247345 in webkit


Ignore:
Timestamp:
Jul 11, 2019 12:34:19 AM (5 years ago)
Author:
Wenson Hsieh
Message:

MobileSafari may crash under -[UIKeyboardTaskExecutionContext transferExecutionToMainThreadWithTask:]
https://bugs.webkit.org/show_bug.cgi?id=199701
<rdar://problem/52590170>

Reviewed by Tim Horton.

Mitigates a crash wherein we end up calling the completion handler of
-requestAutocorrectionContextWithCompletionHandler: within a nested call
to -requestAutocorrectionContextWithCompletionHandler:. In this particular
case, a sync window.open from the web process to the UI process happens
while the UI process is already handling a sync autocorrection context
request. This causes the UI process to try and immediately dispatch the
incoming sync message to avoid deadlock. However, Safari's logic to create
and set up a new web view when opening a new window makes the new view the
first responder, which then prompts UIKit logic to request an autocorrection
context for the new web view.

To avoid the issue for now, simply use -resignFirstResponder as a cue to invoke
pending autocorrection context handlers in the original web view before UIKit
tries to request autocorrection context in the newly created view.

I attempted to write a test for this, but realized that we only end up hitting
the debug assertion pointed out in <https://webkit.org/b/199680>; we should be
able to write a test for this in the future, if we teach Connection to handle
multiple outgoing sync messages.

For the time being, I've attached a manual test case to the bug.

  • UIProcess/ios/WKContentViewInteraction.mm:

(-[WKContentView resignFirstResponderForWebView]):
(-[WKContentView _cancelPendingAutocorrectionContextHandler]):

Add a new helper to signify that a pending autocorrection context handler should be cancelled (invoked
immediately with empty data). Use this in a few places where we currently explicitly pass
-[WKAutocorrectionContext emptyAutocorrectionContext].

(-[WKContentView requestAutocorrectionContextWithCompletionHandler:]):

Location:
trunk/Source/WebKit
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r247344 r247345  
     12019-07-11  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        MobileSafari may crash under -[UIKeyboardTaskExecutionContext transferExecutionToMainThreadWithTask:]
     4        https://bugs.webkit.org/show_bug.cgi?id=199701
     5        <rdar://problem/52590170>
     6
     7        Reviewed by Tim Horton.
     8
     9        Mitigates a crash wherein we end up calling the completion handler of
     10        -requestAutocorrectionContextWithCompletionHandler: within a nested call
     11        to -requestAutocorrectionContextWithCompletionHandler:. In this particular
     12        case, a sync `window.open` from the web process to the UI process happens
     13        while the UI process is already handling a sync autocorrection context
     14        request. This causes the UI process to try and immediately dispatch the
     15        incoming sync message to avoid deadlock. However, Safari's logic to create
     16        and set up a new web view when opening a new window makes the new view the
     17        first responder, which then prompts UIKit logic to request an autocorrection
     18        context for the new web view.
     19
     20        To avoid the issue for now, simply use -resignFirstResponder as a cue to invoke
     21        pending autocorrection context handlers in the original web view before UIKit
     22        tries to request autocorrection context in the newly created view.
     23
     24        I attempted to write a test for this, but realized that we only end up hitting
     25        the debug assertion pointed out in <https://webkit.org/b/199680>; we should be
     26        able to write a test for this in the future, if we teach Connection to handle
     27        multiple outgoing sync messages.
     28
     29        For the time being, I've attached a manual test case to the bug.
     30
     31        * UIProcess/ios/WKContentViewInteraction.mm:
     32        (-[WKContentView resignFirstResponderForWebView]):
     33        (-[WKContentView _cancelPendingAutocorrectionContextHandler]):
     34
     35        Add a new helper to signify that a pending autocorrection context handler should be cancelled (invoked
     36        immediately with empty data). Use this in a few places where we currently explicitly pass
     37        -[WKAutocorrectionContext emptyAutocorrectionContext].
     38
     39        (-[WKContentView requestAutocorrectionContextWithCompletionHandler:]):
     40
    1412019-07-10  Simon Fraser  <simon.fraser@apple.com>
    242
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm

    r247340 r247345  
    12681268
    12691269    [self endEditingAndUpdateFocusAppearanceWithReason:EndEditingReasonResigningFirstResponder];
     1270    [self _cancelPendingAutocorrectionContextHandler];
    12701271
    12711272    // If the user explicitly dismissed the keyboard then we will lose first responder
     
    38663867}
    38673868
     3869- (void)_cancelPendingAutocorrectionContextHandler
     3870{
     3871    [self _invokePendingAutocorrectionContextHandler:WKAutocorrectionContext.emptyAutocorrectionContext];
     3872}
     3873
    38683874- (void)requestAutocorrectionContextWithCompletionHandler:(void (^)(UIWKAutocorrectionContext *autocorrectionContext))completionHandler
    38693875{
     
    38833889    const bool useSyncRequest = true;
    38843890
    3885     [self _invokePendingAutocorrectionContextHandler:WKAutocorrectionContext.emptyAutocorrectionContext];
     3891    [self _cancelPendingAutocorrectionContextHandler];
    38863892
    38873893    _pendingAutocorrectionContextHandler = completionHandler;
     
    38903896    if (useSyncRequest) {
    38913897        _page->process().connection()->waitForAndDispatchImmediately<Messages::WebPageProxy::HandleAutocorrectionContext>(_page->pageID(), 1_s, IPC::WaitForOption::InterruptWaitingIfSyncMessageArrives);
    3892         [self _invokePendingAutocorrectionContextHandler:WKAutocorrectionContext.emptyAutocorrectionContext];
     3898        [self _cancelPendingAutocorrectionContextHandler];
    38933899        return;
    38943900    }
Note: See TracChangeset for help on using the changeset viewer.