Bug 205685 - XMLHTTPRequest POSTs blob data to a custom WKURLSchemeHandler protocol crash
Summary: XMLHTTPRequest POSTs blob data to a custom WKURLSchemeHandler protocol crash
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebKit2 (show other bugs)
Version: Other
Hardware: iPhone / iPad Unspecified
: P2 Normal
Assignee: youenn fablet
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2020-01-02 01:18 PST by mali
Modified: 2020-01-06 14:58 PST (History)
6 users (show)

See Also:


Attachments
the crash demo (88.32 KB, application/zip)
2020-01-05 22:11 PST, mali
no flags Details
Patch (9.15 KB, patch)
2020-01-06 02:32 PST, youenn fablet
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description mali 2020-01-02 01:18:59 PST
problem:  XMLHTTPRequest POSTs blob data to a custom WKURLSchemeHandler protocol will make wkwebview UIProcess crash,The cause of the crash is that the blobRegistry was not initialized


Steps:

1、 Setup custom Scheme
    TestWKURLSchemeHandler *handler = [[TestWKURLSchemeHandler alloc] init];   
    [configuration setURLSchemeHandler:handler forURLScheme:@"test"];


2、launch the  iOS Simultaor 

3、load with url: test://aaa/blobdemo.html 
```
<!DOCTYPE html>
<html>
<head>
<title>blob demo</title>
</head>
<body>
   <script type="text/javascript">
     var blob = new Blob(['blob ', 'foo ', 'bar '], { type: 'plain/text2', endings: 'native' });
     var request = new XMLHttpRequest();
     request.open("POST", "/testblob");
     request.send(blob);
   </script>    
</body>
</html>
```

4、Send a  *blob* XMLHttpRequest with the custom scheme

Result:

UIProcess crash
Comment 1 Alexey Proskuryakov 2020-01-03 22:03:06 PST
Could you please attach a project that reproduces the issue, and a full crash log?
Comment 2 mali 2020-01-05 22:11:28 PST
Created attachment 386811 [details]
the crash demo

use this demo can reproduct  this crash
crash log:
```
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x18)
  * frame #0: 0x00000001b41a2294 WebCore`WebCore::blobRegistry() + 20
    frame #1: 0x00000001b41cd354 WebCore`WebCore::createHTTPBodyCFReadStream(WebCore::FormData&) + 32
    frame #2: 0x00000001b41cdd94 WebCore`WebCore::setHTTPBody(_CFURLRequest*, WebCore::FormData*) + 56
    frame #3: 0x00000001b316f518 WebCore`WebCore::ResourceRequest::doUpdatePlatformHTTPBody() + 120
    frame #4: 0x00000001b41c7284 WebCore`WebCore::ResourceRequestBase::updatePlatformRequest(WebCore::HTTPBodyUpdatePolicy) const + 68
    frame #5: 0x00000001b316e0a4 WebCore`WebCore::ResourceRequest::nsURLRequest(WebCore::HTTPBodyUpdatePolicy) const + 20
    frame #6: 0x00000001b29efc14 WebKit`WebKit::WebURLSchemeTask::nsRequest() const + 68
    frame #7: 0x00000001041d5370 abcd`-[TestWKURLSchemeHandler webView:startURLSchemeTask:](self=0x000000028028c160, _cmd="webView:startURLSchemeTask:", webView=0x000000012801d400, urlSchemeTask=0x00000002800120c0) at ViewController.m:24:24
    frame #8: 0x00000001b2996d10 WebKit`WebKit::WebURLSchemeHandlerCocoa::platformStartTask(WebKit::WebPageProxy&, WebKit::WebURLSchemeTask&) + 128
    frame #9: 0x00000001b29eec74 WebKit`WebKit::WebURLSchemeHandler::startTask(WebKit::WebPageProxy&, WebKit::WebProcessProxy&, unsigned long long, WebCore::ResourceRequest&&, WTF::CompletionHandler<void (WebCore::ResourceResponse const&, WebCore::ResourceError const&, WTF::Vector<char, 0ul, WTF::CrashOnOverflow, 16ul> const&)>&&) + 220
    frame #10: 0x00000001b29bfb90 WebKit`WebKit::WebPageProxy::startURLSchemeTaskShared(WTF::Ref<WebKit::WebProcessProxy, WTF::DumbPtrTraits<WebKit::WebProcessProxy> >&&, WebKit::URLSchemeTaskParameters&&) + 96
    frame #11: 0x00000001b29bfaf8 WebKit`WebKit::WebPageProxy::startURLSchemeTask(WebKit::URLSchemeTaskParameters&&) + 52
    frame #12: 0x00000001b2c0f30c WebKit`WebKit::WebPageProxy::didReceiveMessage(IPC::Connection&, IPC::Decoder&) + 22416
    frame #13: 0x00000001b279d0d4 WebKit`IPC::MessageReceiverMap::dispatchMessage(IPC::Connection&, IPC::Decoder&) + 104
    frame #14: 0x00000001b29eb110 WebKit`WebKit::WebProcessProxy::didReceiveMessage(IPC::Connection&, IPC::Decoder&) + 32
    frame #15: 0x00000001b2787b74 WebKit`IPC::Connection::dispatchMessage(std::__1::unique_ptr<IPC::Decoder, std::__1::default_delete<IPC::Decoder> >) + 204
    frame #16: 0x00000001b278a9d0 WebKit`IPC::Connection::dispatchIncomingMessages() + 404
    frame #17: 0x00000001b9f0389c JavaScriptCore`WTF::RunLoop::performWork() + 276
    frame #18: 0x00000001b9f03b5c JavaScriptCore`WTF::RunLoop::performWork(void*) + 36
    frame #19: 0x00000001ab158a00 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
    frame #20: 0x00000001ab158958 CoreFoundation`__CFRunLoopDoSource0 + 80
    frame #21: 0x00000001ab1580f0 CoreFoundation`__CFRunLoopDoSources0 + 180
    frame #22: 0x00000001ab15323c CoreFoundation`__CFRunLoopRun + 1080
    frame #23: 0x00000001ab152adc CoreFoundation`CFRunLoopRunSpecific + 464
    frame #24: 0x00000001b50d8328 GraphicsServices`GSEventRunModal + 104
    frame #25: 0x00000001af24dae0 UIKitCore`UIApplicationMain + 1936
    frame #26: 0x00000001041d5d08 abcd`main(argc=1, argv=0x000000016bc2f8f0) at main.m:14:16
    frame #27: 0x00000001aafdc360 libdyld.dylib`start + 4
```
Comment 3 mali 2020-01-05 23:14:24 PST
I found that when wkwebview creates the httpbody corresponding to FormData, it will first call the WebCore::blobRegistry method. The return of this method is actually the value of the static variable s_platformStrategies, and this static variable is not initialized, which will cause crash .

```
namespace WebCore {

static PlatformStrategies* s_platformStrategies;

PlatformStrategies* platformStrategies()
{
    ASSERT(s_platformStrategies);
    
    return s_platformStrategies;
}

void setPlatformStrategies(PlatformStrategies* platformStrategies)
{
    if (!s_platformStrategies) {
        s_platformStrategies = platformStrategies;
        return;
    }
    
    // FIXME: This happens when mixing different platform strategies, and we should probably
    // throw an exception here in release builds.
    ASSERT(platformStrategies == s_platformStrategies);
}

}
```
Comment 4 youenn fablet 2020-01-06 00:34:58 PST
Thanks Mali, I reproed the issue and your understanding is correct.
Will fix it.
Comment 5 youenn fablet 2020-01-06 01:40:35 PST
Uploading blobs to custom scheme handler is not yet supported as per https://bugs.webkit.org/show_bug.cgi?id=197237.

The way I was able to repro the crash is to upload XHR with some text and make sure to call xhr.upload so as to set alwaysStream on the FormData.
Comment 6 youenn fablet 2020-01-06 02:32:54 PST
Created attachment 386822 [details]
Patch
Comment 7 mali 2020-01-06 04:17:56 PST
Are there any specific plans to support blob data?
Comment 8 youenn fablet 2020-01-06 05:04:39 PST
(In reply to mali from comment #7)
> Are there any specific plans to support blob data?

Plan is to fix it but I guess this is probably not a high priority.
Any information related to potential use might help bumping the priority.
Comment 9 WebKit Commit Bot 2020-01-06 14:56:40 PST
The commit-queue encountered the following flaky tests while processing attachment 386822 [details]:

transitions/default-timing-function.html bug 138901 (authors: dino@apple.com and graouts@apple.com)
The commit-queue is continuing to process your patch.
Comment 10 WebKit Commit Bot 2020-01-06 14:57:32 PST
Comment on attachment 386822 [details]
Patch

Clearing flags on attachment: 386822

Committed r254089: <https://trac.webkit.org/changeset/254089>
Comment 11 WebKit Commit Bot 2020-01-06 14:57:34 PST
All reviewed patches have been landed.  Closing bug.
Comment 12 Radar WebKit Bug Importer 2020-01-06 14:58:21 PST
<rdar://problem/58355534>