Bug 1486698 - Update Fetch+Stream implementation to throw when the stream is disturbed or locked, r=bz

In this patch, I went through any place in DOM fetch code, where there are
ReadableStreams and update the locked, disturbed, readable checks.

Because we expose streams more often, we need an extra care in the use of
ErrorResult objects. JS streams can now throw exceptions and we need to handle
them.

This patch also fixes a bug in FileStreamReader::CloseAndRelease() which could
be called in case mReader creation fails.
This commit is contained in:
Andrea Marchesini
2018-10-31 18:30:18 +01:00
parent 441c583a33
commit 36a423c3d1
8 changed files with 55 additions and 36 deletions

View File

@@ -239,6 +239,8 @@ Response::Constructor(const GlobalObject& aGlobal,
const fetch::ResponseBodyInit& body = aBody.Value().Value();
if (body.IsReadableStream()) {
aRv.MightThrowJSException();
JSContext* cx = aGlobal.Context();
const ReadableStream& readableStream = body.GetAsReadableStream();
@@ -246,14 +248,12 @@ Response::Constructor(const GlobalObject& aGlobal,
bool disturbed;
bool locked;
bool readable;
if (!JS::ReadableStreamIsDisturbed(cx, readableStreamObj, &disturbed) ||
!JS::ReadableStreamIsLocked(cx, readableStreamObj, &locked) ||
!JS::ReadableStreamIsReadable(cx, readableStreamObj, &readable)) {
!JS::ReadableStreamIsLocked(cx, readableStreamObj, &locked)) {
aRv.StealExceptionFromJSContext(cx);
return nullptr;
}
if (disturbed || locked || !readable) {
if (disturbed || locked) {
aRv.ThrowTypeError<MSG_FETCH_BODY_CONSUMED_ERROR>();
return nullptr;
}
@@ -341,6 +341,29 @@ Response::Clone(JSContext* aCx, ErrorResult& aRv)
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
if (!bodyUsed && mReadableStreamBody) {
aRv.MightThrowJSException();
AutoJSAPI jsapi;
if (!jsapi.Init(mOwner)) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
JSContext* cx = jsapi.cx();
JS::Rooted<JSObject*> body(cx, mReadableStreamBody);
bool locked;
// We just need to check the 'locked' state because GetBodyUsed() already
// checked the 'disturbed' state.
if (!JS::ReadableStreamIsLocked(cx, body, &locked)) {
aRv.StealExceptionFromJSContext(cx);
return nullptr;
}
bodyUsed = locked;
}
if (bodyUsed) {
aRv.ThrowTypeError<MSG_FETCH_BODY_CONSUMED_ERROR>();
return nullptr;