Bug 1128959 - Implement the WHATWG Streams spec - part 15 - setting the correct global when ReadableStream.getReader() is called, r=bz

This commit is contained in:
Andrea Marchesini 2017-08-10 18:04:56 -07:00
parent 60f0e12e3d
commit 76f69afc03
4 changed files with 58 additions and 10 deletions

View File

@ -1158,6 +1158,10 @@ FetchBody<Derived>::LockStream(JSContext* aCx,
JS::HandleObject aStream,
ErrorResult& aRv)
{
MOZ_ASSERT(JS::ReadableStreamGetMode(aStream) ==
JS::ReadableStreamMode::ExternalSource);
// This is native stream, creating a reader will not execute any JS code.
JS::Rooted<JSObject*> reader(aCx,
JS::ReadableStreamGetReader(aCx, aStream,
JS::ReadableStreamReaderMode::Default));

View File

@ -170,17 +170,13 @@ FetchStreamReader::OnOutputStreamReady(nsIAsyncOutputStream* aStream)
return WriteBuffer();
}
AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.Init(mGlobal))) {
CloseAndRelease(NS_ERROR_DOM_INVALID_STATE_ERR);
return NS_ERROR_FAILURE;
}
// TODO: We need to verify this is the correct global per the spec.
// See bug 1385890.
AutoEntryScript aes(mGlobal, "ReadableStreamReader.read", !mWorkerHolder);
JSContext* cx = jsapi.cx();
JS::Rooted<JSObject*> reader(cx, mReader);
JS::Rooted<JSObject*> promise(cx,
JS::ReadableStreamDefaultReaderRead(cx,
JS::Rooted<JSObject*> reader(aes.cx(), mReader);
JS::Rooted<JSObject*> promise(aes.cx(),
JS::ReadableStreamDefaultReaderRead(aes.cx(),
reader));
if (NS_WARN_IF(!promise)) {
// Let's close the stream.

View File

@ -1,6 +1,7 @@
const SAME_COMPARTMENT = "same-compartment";
const IFRAME_COMPARTMENT = "iframe-compartment";
const BIG_BUFFER_SIZE = 1000000;
const ITER_MAX = 10;
function makeBuffer(size) {
let buffer = new Uint8Array(size);
@ -269,6 +270,49 @@ async function test_codeExecution_continue(r, that) {
that.next();
};
async function test_global(compartment) {
info("test_global: " + compartment);
self.foo = 42;
self.iter = ITER_MAX;
let r = new Response(new ReadableStream({
start(c) {
self.controller = c;
},
pull() {
if (!("iter" in self) || self.iter < 0 || self.iter > ITER_MAX) {
throw "Something bad is happening here!"
}
let buffer = new Uint8Array(1);
buffer.fill(self.foo);
self.controller.enqueue(buffer);
if (--self.iter == 0) {
controller.close();
}
}
}));
apply_compartment(compartment,
{ func: "test_global_continue",
args: r });
}
async function test_global_continue(r, that) {
let a = await r.arrayBuffer();
that.is(Object.getPrototypeOf(a), that.ArrayBuffer.prototype, "Body is an array buffer");
that.is(a.byteLength, ITER_MAX, "Body length is correct");
for (let i = 0; i < ITER_MAX; ++i) {
that.is(new Uint8Array(a)[i], 42, "Byte " + i + " is correct");
}
that.next();
};
function workify(func) {
info("Workifing " + func);

View File

@ -48,6 +48,10 @@ let tests = [
function() { test_codeExecution(SAME_COMPARTMENT); },
function() { test_codeExecution(IFRAME_COMPARTMENT); },
function() { test_global(SAME_COMPARTMENT); },
function() { test_global(IFRAME_COMPARTMENT); },
function() { workify('test_global'); },
];
function next() {