Changeset 244400 in webkit


Ignore:
Timestamp:
Apr 17, 2019 1:20:40 PM (5 years ago)
Author:
timothy_horton@apple.com
Message:

UI↔Web deadlock when printing with a JavaScript alert visible
https://bugs.webkit.org/show_bug.cgi?id=196839
<rdar://problem/49157642>

Reviewed by Andy Estes.

Source/WebKit:

  • Platform/IPC/Connection.cpp:

(IPC::Connection::dispatchWorkQueueMessageReceiverMessage):
(IPC::Connection::sendSyncReply):
(IPC::Connection::dispatchSyncMessage):

  • Platform/IPC/Connection.h:

(IPC::Connection::hasOutstandingOutgoingSynchronousReplies const):
Keep track of whether we owe the other side of the connection any
delayed sync replies.

  • UIProcess/API/Cocoa/WKWebView.mm:

(-[WKWebView _webViewPrintFormatter]):
Most actions one can take with a _WKWebViewPrintFormatter involve
synchronously messaging the Web Content process with an infinite timeout.
Doing so while the Web Content process is awaiting a reply to a deferred-reply
synchronous message (like, say, an alert()) results in an app-destroying deadlock.
Instead of that, return a nil _WKWebViewPrintFormatter, indicating to the client
that we can't print right now.

  • UIProcess/ios/WKContentView.mm:

(-[WKContentView _wk_pageCountForPrintFormatter:]):
(-[WKContentView _wk_printedDocument]):
The above isn't sufficient, though, because a sync message could arrive and
be handled between creation and use of the _WKWebViewPrintFormatter.
So, we also bail with a zero page count and null CGPDFDocument immediately
before we would send a sync message to the Web Content process. Clients
handle this less gracefully (e.g. showing a zero page PDF), but it is
very rare compared to the above case.

Tools:

  • TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
  • TestWebKitAPI/Tests/WebKitCocoa/WKWebViewPrintFormatter.mm: Added.

(-[PrintOnAlertUIDelegate webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:]):
(TEST):

Location:
trunk
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r244392 r244400  
     12019-04-17  Tim Horton  <timothy_horton@apple.com>
     2
     3        UI↔Web deadlock when printing with a JavaScript alert visible
     4        https://bugs.webkit.org/show_bug.cgi?id=196839
     5        <rdar://problem/49157642>
     6
     7        Reviewed by Andy Estes.
     8
     9        * Platform/IPC/Connection.cpp:
     10        (IPC::Connection::dispatchWorkQueueMessageReceiverMessage):
     11        (IPC::Connection::sendSyncReply):
     12        (IPC::Connection::dispatchSyncMessage):
     13        * Platform/IPC/Connection.h:
     14        (IPC::Connection::hasOutstandingOutgoingSynchronousReplies const):
     15        Keep track of whether we owe the other side of the connection any
     16        delayed sync replies.
     17
     18        * UIProcess/API/Cocoa/WKWebView.mm:
     19        (-[WKWebView _webViewPrintFormatter]):
     20        Most actions one can take with a _WKWebViewPrintFormatter involve
     21        synchronously messaging the Web Content process with an infinite timeout.
     22        Doing so while the Web Content process is awaiting a reply to a deferred-reply
     23        synchronous message (like, say, an alert()) results in an app-destroying deadlock.
     24        Instead of that, return a nil _WKWebViewPrintFormatter, indicating to the client
     25        that we can't print right now.
     26
     27        * UIProcess/ios/WKContentView.mm:
     28        (-[WKContentView _wk_pageCountForPrintFormatter:]):
     29        (-[WKContentView _wk_printedDocument]):
     30        The above isn't sufficient, though, because a sync message could arrive and
     31        be handled between creation and use of the _WKWebViewPrintFormatter.
     32        So, we also bail with a zero page count and null CGPDFDocument immediately
     33        before we would send a sync message to the Web Content process. Clients
     34        handle this less gracefully (e.g. showing a zero page PDF), but it is
     35        very rare compared to the above case.
     36
    1372019-04-17  Zalan Bujtas  <zalan@apple.com>
    238
  • trunk/Source/WebKit/Platform/IPC/Connection.cpp

    r243345 r244400  
    342342    }
    343343
     344    m_outstandingOutgoingSynchronousReplyCount++;
     345
    344346    auto replyEncoder = std::make_unique<Encoder>("IPC", "SyncMessageReply", syncRequestID);
    345347
     
    459461bool Connection::sendSyncReply(std::unique_ptr<Encoder> encoder)
    460462{
     463    ASSERT(m_outstandingOutgoingSynchronousReplyCount);
     464    m_outstandingOutgoingSynchronousReplyCount--;
     465
    461466    return sendMessage(WTFMove(encoder), { });
    462467}
     
    889894    }
    890895
     896    m_outstandingOutgoingSynchronousReplyCount++;
     897
    891898    auto replyEncoder = std::make_unique<Encoder>("IPC", "SyncMessageReply", syncRequestID);
    892899
  • trunk/Source/WebKit/Platform/IPC/Connection.h

    r244091 r244400  
    197197    bool inSendSync() const { return m_inSendSyncCount; }
    198198
     199    bool hasOutstandingOutgoingSynchronousReplies() const { return m_outstandingOutgoingSynchronousReplyCount; }
     200
    199201    Identifier identifier() const;
    200202
     
    298300    unsigned m_inDispatchMessageMarkedDispatchWhenWaitingForSyncReplyCount;
    299301    unsigned m_inDispatchMessageMarkedToUseFullySynchronousModeForTesting { 0 };
     302    unsigned m_outstandingOutgoingSynchronousReplyCount { 0 };
    300303    bool m_fullySynchronousModeIsAllowedForTesting { false };
    301304    bool m_ignoreTimeoutsForTesting { false };
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm

    r244370 r244400  
    63246324{
    63256325#if !PLATFORM(IOSMAC)
     6326    if (_page->process().connection()->hasOutstandingOutgoingSynchronousReplies())
     6327        return nil;
     6328
    63266329    UIViewPrintFormatter *viewPrintFormatter = self.viewPrintFormatter;
    63276330    ASSERT([viewPrintFormatter isKindOfClass:[_WKWebViewPrintFormatter class]]);
  • trunk/Source/WebKit/UIProcess/ios/WKContentView.mm

    r244085 r244400  
    727727        return 0;
    728728
     729    if (_page->process().connection()->hasOutstandingOutgoingSynchronousReplies())
     730        return 0;
     731
    729732    uint64_t frameID;
    730733    if (_WKFrameHandle *handle = printFormatter.frameToPrint)
     
    770773- (CGPDFDocumentRef)_wk_printedDocument
    771774{
     775    if (_page->process().connection()->hasOutstandingOutgoingSynchronousReplies())
     776        return nullptr;
     777
    772778    if (_isPrintingToPDF) {
    773779        if (!_page->process().connection()->waitForAndDispatchImmediately<Messages::WebPageProxy::DrawToPDFCallback>(_page->pageID(), Seconds::infinity())) {
  • trunk/Tools/ChangeLog

    r244390 r244400  
     12019-04-17  Tim Horton  <timothy_horton@apple.com>
     2
     3        UI↔Web deadlock when printing with a JavaScript alert visible
     4        https://bugs.webkit.org/show_bug.cgi?id=196839
     5        <rdar://problem/49157642>
     6
     7        Reviewed by Andy Estes.
     8
     9        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
     10        * TestWebKitAPI/Tests/WebKitCocoa/WKWebViewPrintFormatter.mm: Added.
     11        (-[PrintOnAlertUIDelegate webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:]):
     12        (TEST):
     13
    1142019-04-17  Alex Christensen  <achristensen@webkit.org>
    215
  • trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

    r244361 r244400  
    9595                2D2BEB2D22324E5F005544CA /* RequestTextInputContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D2BEB2C22324E5F005544CA /* RequestTextInputContext.mm */; };
    9696                2D3CA3A8221DF4B40088E803 /* PageOverlayPlugin.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D3CA3A4221DF2390088E803 /* PageOverlayPlugin.mm */; };
     97                2D41CFB92260014F00FFF335 /* WKWebViewPrintFormatter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D41CFB82260014E00FFF335 /* WKWebViewPrintFormatter.mm */; };
    9798                2D4CF8BD1D8360CC0001CE8D /* WKThumbnailView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D4CF8BC1D8360CC0001CE8D /* WKThumbnailView.mm */; };
    9899                2D51A0C71C8BF00C00765C45 /* DOMHTMLVideoElementWrapper.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D51A0C51C8BF00400765C45 /* DOMHTMLVideoElementWrapper.mm */; };
     
    14511452                2D2BEB2C22324E5F005544CA /* RequestTextInputContext.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RequestTextInputContext.mm; sourceTree = "<group>"; };
    14521453                2D3CA3A4221DF2390088E803 /* PageOverlayPlugin.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PageOverlayPlugin.mm; sourceTree = "<group>"; };
     1454                2D41CFB82260014E00FFF335 /* WKWebViewPrintFormatter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKWebViewPrintFormatter.mm; sourceTree = "<group>"; };
    14531455                2D4CF8BC1D8360CC0001CE8D /* WKThumbnailView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKThumbnailView.mm; path = WebKit/WKThumbnailView.mm; sourceTree = "<group>"; };
    14541456                2D51A0C51C8BF00400765C45 /* DOMHTMLVideoElementWrapper.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMHTMLVideoElementWrapper.mm; sourceTree = "<group>"; };
     
    27152717                                F4106C6821ACBF84004B89A1 /* WKWebViewFirstResponderTests.mm */,
    27162718                                D3BE5E341E4CE85E00FD563A /* WKWebViewGetContents.mm */,
     2719                                2D41CFB82260014E00FFF335 /* WKWebViewPrintFormatter.mm */,
    27172720                                37A9DBE7213B4C9300D261A2 /* WKWebViewServerTrustKVC.mm */,
    27182721                                93F56DA81E5F9181003EDE84 /* WKWebViewSnapshot.mm */,
     
    44474450                                D34E08761E4E42E1005FF14A /* WKWebViewGetContents.mm in Sources */,
    44484451                                F4FA91811E61849B007B8C1D /* WKWebViewMacEditingTests.mm in Sources */,
     4452                                2D41CFB92260014F00FFF335 /* WKWebViewPrintFormatter.mm in Sources */,
    44494453                                37A9DBE9213B4C9300D261A2 /* WKWebViewServerTrustKVC.mm in Sources */,
    44504454                                93F56DA91E5F919D003EDE84 /* WKWebViewSnapshot.mm in Sources */,
Note: See TracChangeset for help on using the changeset viewer.