Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: cherry-pick f0a63e1f361f from chromium #32012

Merged
merged 10 commits into from Jan 13, 2022
1 change: 1 addition & 0 deletions patches/chromium/.patches
Expand Up @@ -121,6 +121,7 @@ cherry-pick-1a8af2da50e4.patch
cherry-pick-a5f54612590d.patch
cachestorage_store_partial_opaque_responses.patch
fix_aspect_ratio_with_max_size.patch
cherry-pick-f0a63e1f361f.patch
cherry-pick-6bb320d134b1.patch
cherry-pick-109fde1088be.patch
m96_fileapi_move_origin_checks_in_bloburlstore_sooner.patch
Expand Down
245 changes: 245 additions & 0 deletions patches/chromium/cherry-pick-f0a63e1f361f.patch
@@ -0,0 +1,245 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Adam Rice <ricea@chromium.org>
Date: Sat, 6 Nov 2021 18:52:26 +0000
Subject: Return undefined from UnderlyingSinkBase "type" getter

The "type" attribute of an object passed to the WritableStream
constructor is supposed to return undefined. Add a getter to
UnderlyingSinkBase to ensure it always does.

Add tests to verify that "type" is not inherited from
Object.prototype.type.

Move some methods out-of-line into a new underlying_sink_base.cc file.

Make WritableStreamDefaultController::From() more robust.

BUG=1262791

(cherry picked from commit 26564c88bc9e034cc512afd857cf303193647b9a)

Change-Id: I97f43233eef0e473fb1a22a3ea8afafe92e16266
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3252171
Reviewed-by: Yutaka Hirano <yhirano@chromium.org>
Commit-Queue: Adam Rice <ricea@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#936834}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3266824
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/4664@{#806}
Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512}

diff --git a/third_party/blink/renderer/core/streams/build.gni b/third_party/blink/renderer/core/streams/build.gni
index 57a106353bd6720bc7da88f96dce66e4332aea2a..744d47f1a1e9352cc4df56ce89635b3d6f8b5425 100644
--- a/third_party/blink/renderer/core/streams/build.gni
+++ b/third_party/blink/renderer/core/streams/build.gni
@@ -43,6 +43,7 @@ blink_core_sources_streams = [
"transform_stream_default_controller.cc",
"transform_stream_default_controller.h",
"transform_stream_transformer.h",
+ "underlying_sink_base.cc",
"underlying_sink_base.h",
"underlying_source_base.cc",
"underlying_source_base.h",
diff --git a/third_party/blink/renderer/core/streams/underlying_sink_base.cc b/third_party/blink/renderer/core/streams/underlying_sink_base.cc
new file mode 100644
index 0000000000000000000000000000000000000000..a10d4f1865fc4e11c90f463b64ff666cce0fba69
--- /dev/null
+++ b/third_party/blink/renderer/core/streams/underlying_sink_base.cc
@@ -0,0 +1,29 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/streams/underlying_sink_base.h"
+
+#include "third_party/blink/renderer/core/streams/writable_stream_default_controller.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+
+ScriptPromise UnderlyingSinkBase::start(ScriptState* script_state,
+ ScriptValue controller,
+ ExceptionState& exception_state) {
+ controller_ = WritableStreamDefaultController::From(script_state, controller);
+ return start(script_state, controller_, exception_state);
+}
+
+ScriptValue UnderlyingSinkBase::type(ScriptState* script_state) const {
+ auto* isolate = script_state->GetIsolate();
+ return ScriptValue(isolate, v8::Undefined(isolate));
+}
+
+void UnderlyingSinkBase::Trace(Visitor* visitor) const {
+ visitor->Trace(controller_);
+ ScriptWrappable::Trace(visitor);
+}
+
+} // namespace blink
diff --git a/third_party/blink/renderer/core/streams/underlying_sink_base.h b/third_party/blink/renderer/core/streams/underlying_sink_base.h
index 3b07d87f064a26e01c4ee827d78fca005049c90a..07ba729fc3a78cf2102e2d64e527048af8be9c71 100644
--- a/third_party/blink/renderer/core/streams/underlying_sink_base.h
+++ b/third_party/blink/renderer/core/streams/underlying_sink_base.h
@@ -6,16 +6,20 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_UNDERLYING_SINK_BASE_H_

#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/streams/writable_stream_default_controller.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"

+// Various files depend on us exporting this header.
+// TODO(ricea): Clean up the dependencies and remove this include.
+#include "third_party/blink/renderer/core/streams/writable_stream_default_controller.h"
+
namespace blink {

class ExceptionState;
-class ScriptValue;
class ScriptState;
+class WritableStreamDefaultController;

class CORE_EXPORT UnderlyingSinkBase : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
@@ -38,12 +42,8 @@ class CORE_EXPORT UnderlyingSinkBase : public ScriptWrappable {
ScriptValue reason,
ExceptionState&) = 0;

- ScriptPromise start(ScriptState* script_state,
- ScriptValue controller,
- ExceptionState& exception_state) {
- controller_ = WritableStreamDefaultController::From(controller);
- return start(script_state, controller_, exception_state);
- }
+ ScriptPromise start(ScriptState*, ScriptValue controller, ExceptionState&);
+
ScriptPromise write(ScriptState* script_state,
ScriptValue chunk,
ScriptValue controller,
@@ -52,10 +52,11 @@ class CORE_EXPORT UnderlyingSinkBase : public ScriptWrappable {
return write(script_state, chunk, controller_, exception_state);
}

- void Trace(Visitor* visitor) const override {
- visitor->Trace(controller_);
- ScriptWrappable::Trace(visitor);
- }
+ // Returns a JavaScript "undefined" value. This is required by the
+ // WritableStream Create() method.
+ ScriptValue type(ScriptState*) const;
+
+ void Trace(Visitor*) const override;

protected:
WritableStreamDefaultController* Controller() const { return controller_; }
diff --git a/third_party/blink/renderer/core/streams/underlying_sink_base.idl b/third_party/blink/renderer/core/streams/underlying_sink_base.idl
index 8351141cbc07ed32566a0006f998aab61e8fd6b5..470eb527b11e3dce355d724eaa63ec981b7788e4 100644
--- a/third_party/blink/renderer/core/streams/underlying_sink_base.idl
+++ b/third_party/blink/renderer/core/streams/underlying_sink_base.idl
@@ -14,4 +14,7 @@ interface UnderlyingSinkBase {
[CallWith=ScriptState, RaisesException] Promise<void> write(any chunk, any controller);
[CallWith=ScriptState, RaisesException] Promise<void> close();
[CallWith=ScriptState, RaisesException] Promise<void> abort(any reason);
+
+ // This only exists to prevent Object.prototype.type being accessed.
+ [CallWith=ScriptState] readonly attribute any type;
};
diff --git a/third_party/blink/renderer/core/streams/writable_stream_default_controller.cc b/third_party/blink/renderer/core/streams/writable_stream_default_controller.cc
index 0b22eedcddc87b0ac695389a76ed5e353dd5f92c..bc959b6c33dbba6a367b4d247d56b67698299635 100644
--- a/third_party/blink/renderer/core/streams/writable_stream_default_controller.cc
+++ b/third_party/blink/renderer/core/streams/writable_stream_default_controller.cc
@@ -20,10 +20,14 @@
namespace blink {

WritableStreamDefaultController* WritableStreamDefaultController::From(
+ ScriptState* script_state,
ScriptValue controller) {
- DCHECK(controller.IsObject());
- return V8WritableStreamDefaultController::ToImpl(
- controller.V8Value().As<v8::Object>());
+ CHECK(controller.IsObject());
+ auto* controller_impl =
+ V8WritableStreamDefaultController::ToImplWithTypeCheck(
+ script_state->GetIsolate(), controller.V8Value().As<v8::Object>());
+ CHECK(controller_impl);
+ return controller_impl;
}

// Only used internally. Not reachable from JavaScript.
diff --git a/third_party/blink/renderer/core/streams/writable_stream_default_controller.h b/third_party/blink/renderer/core/streams/writable_stream_default_controller.h
index 3351dcd6941360fc9fecaa8c03080da813a5b6a2..8be676421763caa911b8d003c869856675e28713 100644
--- a/third_party/blink/renderer/core/streams/writable_stream_default_controller.h
+++ b/third_party/blink/renderer/core/streams/writable_stream_default_controller.h
@@ -27,7 +27,7 @@ class CORE_EXPORT WritableStreamDefaultController final
DEFINE_WRAPPERTYPEINFO();

public:
- static WritableStreamDefaultController* From(ScriptValue);
+ static WritableStreamDefaultController* From(ScriptState*, ScriptValue);

// The JavaScript-exposed constructor throws automatically as no constructor
// is specified in the IDL. This constructor is used internally during
diff --git a/third_party/blink/web_tests/http/tests/streams/chromium/underlying-sink-base-type-getter.html b/third_party/blink/web_tests/http/tests/streams/chromium/underlying-sink-base-type-getter.html
new file mode 100644
index 0000000000000000000000000000000000000000..fbbc26b08ea4e310ed99b7a02e1a7952e8f60921
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/streams/chromium/underlying-sink-base-type-getter.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+'use strict';
+
+test(t => {
+ Object.defineProperty(Object.prototype, 'type',
+ {
+ configurable: true,
+ get() {
+ throw Error();
+ }
+ });
+ t.add_cleanup(() => {
+ delete Object.prototype.type;
+ });
+ const generator = new MediaStreamTrackGenerator('video');
+ // The WritableStream is created lazily, so access it to trigger creation.
+ generator.writable.getWriter();
+}, 'a throwing getter on Object.prototype.type should not interfere with ' +
+ 'native writable stream creation');
+
+test(t => {
+ Object.defineProperty(Object.prototype, 'type',
+ {
+ configurable: true,
+ get() {
+ this.start(0x414141);
+ }
+ });
+ t.add_cleanup(() => {
+ delete Object.prototype.type;
+ });
+ const generator = new MediaStreamTrackGenerator('video');
+ generator.writable.getWriter();
+}, 'a getter that calls start() with a number on Object.prototype.type ' +
+ 'should not interfere with native writable stream creation');
+
+test(t => {
+ Object.defineProperty(Object.prototype, 'type',
+ {
+ configurable: true,
+ get() {
+ this.start({});
+ }
+ });
+ t.add_cleanup(() => {
+ delete Object.prototype.type;
+ });
+ const generator = new MediaStreamTrackGenerator('video');
+ generator.writable.getWriter();
+}, 'a getter that calls start() with an object on Object.prototype.type ' +
+ 'should not interfere with native writable stream creation');
+
+</script>