Commit 7712d138 authored by Yutaka Hirano's avatar Yutaka Hirano Committed by Commit Bot

ReadableStreamBytesConsumer should check read results

ReadableStreamBytesConsumer expected that the results from
ReadableStreamReaderDefaultRead should be Promise<Object> because that
is provided from ReadableStream provided by blink, but it's possible to
inject arbitrary values with the promise assimilation.

This CL adds additional checks for such injection.

Bug: 840320
Change-Id: I7b3c6a8bfcf563dd860b133ff0295dd7a5d5fea5
Reviewed-on: https://chromium-review.googlesource.com/1049413
Commit-Queue: Yutaka Hirano <yhirano@chromium.org>
Reviewed-by: default avatarAdam Rice <ricea@chromium.org>
Cr-Commit-Position: refs/heads/master@{#556751}
parent 4a9e4119
// META: script=../resources/utils.js
promise_test(async () => {
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();
assert_equals(text, 'bye', 'The valud should be replaced with "bye".');
}, '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});
};
promise_rejects(t, TypeError(), resp.text(),
'The value should be replaced with undefined.');
}, 'Inject {done: false, 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);
};
promise_rejects(t, TypeError(), resp.text(),
'The read result should be replaced with undefined.');
}, '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);
};
promise_rejects(t, TypeError(), resp.text(),
'The read result should be replaced with a number.');
}, 'Inject 8.2 via Object.prototype.then.');
......@@ -33,10 +33,17 @@ class ReadableStreamBytesConsumer::OnFulfilled final : public ScriptFunction {
ScriptValue Call(ScriptValue v) override {
bool done;
v8::Local<v8::Value> item = v.V8Value();
DCHECK(item->IsObject());
v8::Local<v8::Value> value =
V8UnpackIteratorResult(v.GetScriptState(), item.As<v8::Object>(), &done)
.ToLocalChecked();
if (!item->IsObject()) {
consumer_->OnRejected();
return ScriptValue();
}
v8::Local<v8::Value> value;
if (!V8UnpackIteratorResult(v.GetScriptState(), item.As<v8::Object>(),
&done)
.ToLocal(&value)) {
consumer_->OnRejected();
return ScriptValue();
}
if (done) {
consumer_->OnReadDone();
return v;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment