mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-11-12 06:08:24 +02:00
Automatic update from web-platform-testsUpdate ReadableStream to match standard Apply standard changes to ReadableStream up to standard version 51227372cc84846bdcf68312724c4cac6a4b9e58. With this change, Blink's implementation once again passes all non-byte-stream ReadableStream tests. Update test expectations to match. Changes: * Use null prototypes for the objects returned by ReadableStreamDefaultReaderRead when they consumed internally by pipeTo(), tee() or fetch. This is the fix for standard issue https://github.com/whatwg/streams/issues/933 "Setting Object.prototype.then permits interfering with pipeTo() internals". * In pipeTo() complete all pending writes when readable stream is errored. * Change ordering of accessing strategy parameters to match standard. Non-user visible changes: * Use Object.assign() to be more concise when modifying the binding object in ReadableStream.js and WritableStream.js. WPT changes: * Update the expectations in response-stream-with-broken-then.any.js since interference is no longer possible. * Add extra tests to response-stream-with-broken-then.any.js for the arraybuffer -> text case which should have been broken in Chrome but wasn't, and the arraybuffer -> stream case. * Fix bugs in streams/piping/then-interception.js which are only apparent when it passes. In particular, delete Object.prototype.then even when it is not called. BUG=866388 Change-Id: I82c8ac2c2b7d71ccbf331388014e8cec847e1b65 Reviewed-on: https://chromium-review.googlesource.com/1149678 Reviewed-by: Yutaka Hirano <yhirano@chromium.org> Commit-Queue: Adam Rice <ricea@chromium.org> Cr-Commit-Position: refs/heads/master@{#580057} -- wpt-commits: 4e98c23a16efc0eb6ea4c305e3f48def3cac4643 wpt-pr: 12178
116 lines
4 KiB
JavaScript
116 lines
4 KiB
JavaScript
// META: script=../resources/utils.js
|
|
|
|
promise_test(async () => {
|
|
// t.add_cleanup doesn't work when Object.prototype.then is overwritten, so
|
|
// these tests use add_completion_callback for cleanup instead.
|
|
add_completion_callback(() => delete Object.prototype.then);
|
|
const hello = new TextEncoder().encode('hello');
|
|
const bye = new TextEncoder().encode('bye');
|
|
const rs = new ReadableStream({
|
|
start(controller) {
|
|
controller.enqueue(hello);
|
|
controller.close();
|
|
}
|
|
});
|
|
const resp = new Response(rs);
|
|
Object.prototype.then = (onFulfilled) => {
|
|
delete Object.prototype.then;
|
|
onFulfilled({done: false, value: bye});
|
|
};
|
|
const text = await resp.text();
|
|
delete Object.prototype.then;
|
|
assert_equals(text, 'hello', 'The value should be "hello".');
|
|
}, 'Attempt to inject {done: false, value: bye} via Object.prototype.then.');
|
|
|
|
promise_test(async (t) => {
|
|
add_completion_callback(() => delete Object.prototype.then);
|
|
const hello = new TextEncoder().encode('hello');
|
|
const rs = new ReadableStream({
|
|
start(controller) {
|
|
controller.enqueue(hello);
|
|
controller.close();
|
|
}
|
|
});
|
|
const resp = new Response(rs);
|
|
Object.prototype.then = (onFulfilled) => {
|
|
delete Object.prototype.then;
|
|
onFulfilled({done: false, value: undefined});
|
|
};
|
|
const text = await resp.text();
|
|
delete Object.prototype.then;
|
|
assert_equals(text, 'hello', 'The value should be "hello".');
|
|
}, 'Attempt to inject value: undefined via Object.prototype.then.');
|
|
|
|
promise_test(async (t) => {
|
|
add_completion_callback(() => delete Object.prototype.then);
|
|
const hello = new TextEncoder().encode('hello');
|
|
const rs = new ReadableStream({
|
|
start(controller) {
|
|
controller.enqueue(hello);
|
|
controller.close();
|
|
}
|
|
});
|
|
const resp = new Response(rs);
|
|
Object.prototype.then = (onFulfilled) => {
|
|
delete Object.prototype.then;
|
|
onFulfilled(undefined);
|
|
};
|
|
const text = await resp.text();
|
|
delete Object.prototype.then;
|
|
assert_equals(text, 'hello', 'The value should be "hello".');
|
|
}, 'Attempt to inject undefined via Object.prototype.then.');
|
|
|
|
promise_test(async (t) => {
|
|
add_completion_callback(() => delete Object.prototype.then);
|
|
const hello = new TextEncoder().encode('hello');
|
|
const rs = new ReadableStream({
|
|
start(controller) {
|
|
controller.enqueue(hello);
|
|
controller.close();
|
|
}
|
|
});
|
|
const resp = new Response(rs);
|
|
Object.prototype.then = (onFulfilled) => {
|
|
delete Object.prototype.then;
|
|
onFulfilled(8.2);
|
|
};
|
|
const text = await resp.text();
|
|
delete Object.prototype.then;
|
|
assert_equals(text, 'hello', 'The value should be "hello".');
|
|
}, 'Attempt to inject 8.2 via Object.prototype.then.');
|
|
|
|
promise_test(async () => {
|
|
add_completion_callback(() => delete Object.prototype.then);
|
|
const hello = new TextEncoder().encode('hello');
|
|
const bye = new TextEncoder().encode('bye');
|
|
const resp = new Response(hello);
|
|
Object.prototype.then = (onFulfilled) => {
|
|
delete Object.prototype.then;
|
|
onFulfilled({done: false, value: bye});
|
|
};
|
|
const text = await resp.text();
|
|
delete Object.prototype.then;
|
|
assert_equals(text, 'hello', 'The value should be "hello".');
|
|
}, 'intercepting arraybuffer to text conversion via Object.prototype.then ' +
|
|
'should not be possible');
|
|
|
|
promise_test(async () => {
|
|
add_completion_callback(() => delete Object.prototype.then);
|
|
const u8a123 = new Uint8Array([1, 2, 3]);
|
|
const u8a456 = new Uint8Array([4, 5, 6]);
|
|
const resp = new Response(u8a123);
|
|
const writtenBytes = [];
|
|
const ws = new WritableStream({
|
|
write(chunk) {
|
|
writtenBytes.push(...Array.from(chunk));
|
|
}
|
|
});
|
|
Object.prototype.then = (onFulfilled) => {
|
|
delete Object.prototype.then;
|
|
onFulfilled({done: false, value: u8a456});
|
|
};
|
|
await resp.body.pipeTo(ws);
|
|
delete Object.prototype.then;
|
|
assert_array_equals(writtenBytes, u8a123, 'The value should be [1, 2, 3]');
|
|
}, 'intercepting arraybuffer to body readable stream conversion via ' +
|
|
'Object.prototype.then should not be possible');
|