Skip to content

Commit 2c8cfdb

Browse files
author
Mark Lam
committed
ReadableStream::create() should handle any exceptions that may be thrown during construction.
https://bugs.webkit.org/show_bug.cgi?id=213819 Reviewed by Youenn Fablet and Yusuke Suzuki. Win EWS detected that ReadableStream::create() can throw exceptions, and we were failing to handle it. This patch fixes that. * Modules/cache/DOMCache.cpp: (WebCore::DOMCache::put): * Modules/fetch/FetchBodyOwner.cpp: (WebCore::FetchBodyOwner::readableStream): (WebCore::FetchBodyOwner::createReadableStream): * Modules/fetch/FetchBodyOwner.h: * Modules/fetch/FetchResponse.cpp: (WebCore::FetchResponse::clone): * bindings/js/ReadableStream.cpp: (WebCore::ReadableStream::create): * bindings/js/ReadableStream.h: Canonical link: https://commits.webkit.org/226711@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@263883 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent fc8015c commit 2c8cfdb

7 files changed

Lines changed: 74 additions & 23 deletions

File tree

Source/WebCore/ChangeLog

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1+
2020-07-02 Mark Lam <[email protected]>
2+
3+
ReadableStream::create() should handle any exceptions that may be thrown during construction.
4+
https://bugs.webkit.org/show_bug.cgi?id=213819
5+
6+
Reviewed by Youenn Fablet and Yusuke Suzuki.
7+
8+
Win EWS detected that ReadableStream::create() can throw exceptions, and we were
9+
failing to handle it. This patch fixes that.
10+
11+
* Modules/cache/DOMCache.cpp:
12+
(WebCore::DOMCache::put):
13+
* Modules/fetch/FetchBodyOwner.cpp:
14+
(WebCore::FetchBodyOwner::readableStream):
15+
(WebCore::FetchBodyOwner::createReadableStream):
16+
* Modules/fetch/FetchBodyOwner.h:
17+
* Modules/fetch/FetchResponse.cpp:
18+
(WebCore::FetchResponse::clone):
19+
* bindings/js/ReadableStream.cpp:
20+
(WebCore::ReadableStream::create):
21+
* bindings/js/ReadableStream.h:
22+
123
2020-07-02 Alex Christensen <[email protected]>
224

325
Update Mac CMake build

Source/WebCore/Modules/cache/DOMCache.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2017 Apple Inc. All rights reserved.
2+
* Copyright (C) 2017-2020 Apple Inc. All rights reserved.
33
*
44
* Redistribution and use in source and binary forms, with or without
55
* modification, are permitted provided that the following conditions
@@ -365,8 +365,13 @@ void DOMCache::put(RequestInfo&& info, Ref<FetchResponse>&& response, DOMPromise
365365
}
366366

367367
// FIXME: for efficiency, we should load blobs directly instead of going through the readableStream path.
368-
if (response->isBlobBody())
369-
response->readableStream(*scriptExecutionContext()->execState());
368+
if (response->isBlobBody()) {
369+
auto streamOrException = response->readableStream(*scriptExecutionContext()->execState());
370+
if (UNLIKELY(streamOrException.hasException())) {
371+
promise.reject(streamOrException.releaseException());
372+
return;
373+
}
374+
}
370375

371376
if (response->isBodyReceivedByChunk()) {
372377
auto& responseRef = response.get();

Source/WebCore/Modules/fetch/FetchBodyOwner.cpp

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
* Copyright (C) 2016 Canon Inc.
3+
* Copyright (C) 2020 Apple Inc. All rights reserved.
34
*
45
* Redistribution and use in source and binary forms, with or without
56
* modification, are permitted, provided that the following conditions
@@ -311,27 +312,40 @@ void FetchBodyOwner::BlobLoader::didFail(const ResourceError&)
311312
owner.blobLoadingFailed();
312313
}
313314

314-
RefPtr<ReadableStream> FetchBodyOwner::readableStream(JSC::JSGlobalObject& state)
315+
ExceptionOr<RefPtr<ReadableStream>> FetchBodyOwner::readableStream(JSC::JSGlobalObject& state)
315316
{
316317
if (isBodyNullOrOpaque())
317318
return nullptr;
318319

319-
if (!m_body->hasReadableStream())
320-
createReadableStream(state);
320+
if (!m_body->hasReadableStream()) {
321+
auto voidOrException = createReadableStream(state);
322+
if (UNLIKELY(voidOrException.hasException()))
323+
return voidOrException.releaseException();
324+
}
321325

322326
return m_body->readableStream();
323327
}
324328

325-
void FetchBodyOwner::createReadableStream(JSC::JSGlobalObject& state)
329+
ExceptionOr<void> FetchBodyOwner::createReadableStream(JSC::JSGlobalObject& state)
326330
{
327331
ASSERT(!m_readableStreamSource);
328332
if (isDisturbed()) {
329-
m_body->setReadableStream(ReadableStream::create(state, nullptr));
333+
auto streamOrException = ReadableStream::create(state, nullptr);
334+
if (UNLIKELY(streamOrException.hasException()))
335+
return streamOrException.releaseException();
336+
m_body->setReadableStream(streamOrException.releaseReturnValue());
330337
m_body->readableStream()->lock();
331-
} else {
332-
m_readableStreamSource = adoptRef(*new FetchBodySource(*this));
333-
m_body->setReadableStream(ReadableStream::create(state, m_readableStreamSource));
338+
return { };
334339
}
340+
341+
m_readableStreamSource = adoptRef(*new FetchBodySource(*this));
342+
auto streamOrException = ReadableStream::create(state, m_readableStreamSource);
343+
if (UNLIKELY(streamOrException.hasException())) {
344+
m_readableStreamSource = nullptr;
345+
return streamOrException.releaseException();
346+
}
347+
m_body->setReadableStream(streamOrException.releaseReturnValue());
348+
return { };
335349
}
336350

337351
void FetchBodyOwner::consumeBodyAsStream()

Source/WebCore/Modules/fetch/FetchBodyOwner.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
* Copyright (C) 2016 Canon Inc.
3+
* Copyright (C) 2020 Apple Inc. All rights reserved.
34
*
45
* Redistribution and use in source and binary forms, with or without
56
* modification, are permitted, provided that the following conditions
@@ -29,6 +30,7 @@
2930
#pragma once
3031

3132
#include "ActiveDOMObject.h"
33+
#include "ExceptionOr.h"
3234
#include "FetchBody.h"
3335
#include "FetchBodySource.h"
3436
#include "FetchHeaders.h"
@@ -57,7 +59,7 @@ class FetchBodyOwner : public RefCounted<FetchBodyOwner>, public ActiveDOMObject
5759

5860
bool isActive() const { return !!m_blobLoader; }
5961

60-
RefPtr<ReadableStream> readableStream(JSC::JSGlobalObject&);
62+
ExceptionOr<RefPtr<ReadableStream>> readableStream(JSC::JSGlobalObject&);
6163
bool hasReadableStreamBody() const { return m_body && m_body->hasReadableStream(); }
6264

6365
virtual void consumeBodyAsStream();
@@ -80,7 +82,7 @@ class FetchBodyOwner : public RefCounted<FetchBodyOwner>, public ActiveDOMObject
8082
void consumeOnceLoadingFinished(FetchBodyConsumer::Type, Ref<DeferredPromise>&&);
8183

8284
void setBody(FetchBody&& body) { m_body = WTFMove(body); }
83-
void createReadableStream(JSC::JSGlobalObject&);
85+
ExceptionOr<void> createReadableStream(JSC::JSGlobalObject&);
8486

8587
// ActiveDOMObject API
8688
void stop() override;

Source/WebCore/Modules/fetch/FetchResponse.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
* Copyright (C) 2016 Canon Inc.
3+
* Copyright (C) 2020 Apple Inc. All rights reserved.
34
*
45
* Redistribution and use in source and binary forms, with or without
56
* modification, are permitted, provided that the following conditions
@@ -176,8 +177,11 @@ ExceptionOr<Ref<FetchResponse>> FetchResponse::clone(ScriptExecutionContext& con
176177
ASSERT(scriptExecutionContext());
177178

178179
// If loading, let's create a stream so that data is teed on both clones.
179-
if (isLoading() && !m_readableStreamSource)
180-
createReadableStream(*context.execState());
180+
if (isLoading() && !m_readableStreamSource) {
181+
auto voidOrException = createReadableStream(*context.execState());
182+
if (UNLIKELY(voidOrException.hasException()))
183+
return voidOrException.releaseException();
184+
}
181185

182186
// Synthetic responses do not store headers in m_internalResponse.
183187
if (m_internalResponse.type() == ResourceResponse::Type::Default)

Source/WebCore/bindings/js/ReadableStream.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2017 Apple Inc. All rights reserved.
2+
* Copyright (C) 2017-2020 Apple Inc. All rights reserved.
33
*
44
* Redistribution and use in source and binary forms, with or without
55
* modification, are permitted provided that the following conditions
@@ -26,6 +26,8 @@
2626
#include "config.h"
2727
#include "ReadableStream.h"
2828

29+
#include "Exception.h"
30+
#include "ExceptionCode.h"
2931
#include "JSDOMConvertSequences.h"
3032
#include "JSReadableStreamSink.h"
3133
#include "JSReadableStreamSource.h"
@@ -35,10 +37,10 @@
3537
namespace WebCore {
3638
using namespace JSC;
3739

38-
Ref<ReadableStream> ReadableStream::create(JSC::JSGlobalObject& lexicalGlobalObject, RefPtr<ReadableStreamSource>&& source)
40+
ExceptionOr<Ref<ReadableStream>> ReadableStream::create(JSC::JSGlobalObject& lexicalGlobalObject, RefPtr<ReadableStreamSource>&& source)
3941
{
4042
VM& vm = lexicalGlobalObject.vm();
41-
auto scope = DECLARE_CATCH_SCOPE(vm);
43+
auto scope = DECLARE_THROW_SCOPE(vm);
4244

4345
auto& clientData = *static_cast<JSVMClientData*>(vm.clientData);
4446
auto& globalObject = *JSC::jsCast<JSDOMGlobalObject*>(&lexicalGlobalObject);
@@ -52,10 +54,11 @@ Ref<ReadableStream> ReadableStream::create(JSC::JSGlobalObject& lexicalGlobalObj
5254
args.append(source ? toJSNewlyCreated(&lexicalGlobalObject, &globalObject, source.releaseNonNull()) : JSC::jsUndefined());
5355
ASSERT(!args.hasOverflowed());
5456

55-
auto newReadableStream = jsDynamicCast<JSReadableStream*>(vm, JSC::construct(&lexicalGlobalObject, constructor, constructData, args));
56-
scope.assertNoException();
57+
JSObject* object = JSC::construct(&lexicalGlobalObject, constructor, constructData, args);
58+
ASSERT(!!scope.exception() == !object);
59+
RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError });
5760

58-
return create(globalObject, *newReadableStream);
61+
return create(globalObject, *jsCast<JSReadableStream*>(object));
5962
}
6063

6164
namespace ReadableStreamInternal {

Source/WebCore/bindings/js/ReadableStream.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2017 Apple Inc. All rights reserved.
2+
* Copyright (C) 2017-2020 Apple Inc. All rights reserved.
33
*
44
* Redistribution and use in source and binary forms, with or without
55
* modification, are permitted provided that the following conditions
@@ -25,6 +25,7 @@
2525

2626
#pragma once
2727

28+
#include "ExceptionOr.h"
2829
#include "JSDOMBinding.h"
2930
#include "JSDOMConvert.h"
3031
#include "JSDOMGuardedObject.h"
@@ -39,7 +40,7 @@ class ReadableStream final : public DOMGuarded<JSReadableStream> {
3940
public:
4041
static Ref<ReadableStream> create(JSDOMGlobalObject& globalObject, JSReadableStream& readableStream) { return adoptRef(*new ReadableStream(globalObject, readableStream)); }
4142

42-
static Ref<ReadableStream> create(JSC::JSGlobalObject&, RefPtr<ReadableStreamSource>&&);
43+
static ExceptionOr<Ref<ReadableStream>> create(JSC::JSGlobalObject&, RefPtr<ReadableStreamSource>&&);
4344

4445
WEBCORE_EXPORT static bool isDisturbed(JSC::JSGlobalObject&, JSC::JSValue);
4546

0 commit comments

Comments
 (0)