blob: 8fef66c8a281c6248fd36763889bc95aa899f7cc [file] [log] [blame]
// META: global=window,worker
// 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');