Title: [264916] releases/WebKitGTK/webkit-2.28
Revision
264916
Author
carlo...@webkit.org
Date
2020-07-27 03:48:31 -0700 (Mon, 27 Jul 2020)

Log Message

Merge r263141 - Make ReadableStream robust against user code
https://bugs.webkit.org/show_bug.cgi?id=212915
<rdar://problem/64133221>

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

We now get pull/cancel only once from the source.

* web-platform-tests/streams/readable-streams/bad-underlying-sources-expected.txt:
* web-platform-tests/streams/readable-streams/bad-underlying-sources.dedicatedworker-expected.txt:
* web-platform-tests/streams/readable-streams/bad-underlying-sources.serviceworker.https-expected.txt:

Source/WebCore:

Create tee source with private slots instead of public ones.
When source has one of this private slot, we directly go to the creation of a ReadableStream.
Covered by existing tests.

* Modules/streams/ReadableStream.js:
(initializeReadableStream):
* Modules/streams/ReadableStreamInternals.js:
(setupReadableStreamDefaultController):
(readableStreamTee):
(readableStreamDefaultControllerCallPullIfNeeded):
(readableStreamDefaultControllerCancel):
* Modules/streams/StreamInternals.js:
(promiseInvokeOrNoopMethodNoCatch):
(promiseInvokeOrNoopNoCatch):
(promiseInvokeOrNoopMethod):
(promiseInvokeOrNoop):
* bindings/js/WebCoreBuiltinNames.h:

Modified Paths

Diff

Modified: releases/WebKitGTK/webkit-2.28/LayoutTests/imported/w3c/ChangeLog (264915 => 264916)


--- releases/WebKitGTK/webkit-2.28/LayoutTests/imported/w3c/ChangeLog	2020-07-27 10:48:23 UTC (rev 264915)
+++ releases/WebKitGTK/webkit-2.28/LayoutTests/imported/w3c/ChangeLog	2020-07-27 10:48:31 UTC (rev 264916)
@@ -1,3 +1,17 @@
+2020-06-17  Youenn Fablet  <you...@apple.com>
+
+        Make ReadableStream robust against user code
+        https://bugs.webkit.org/show_bug.cgi?id=212915
+        <rdar://problem/64133221>
+
+        Reviewed by Darin Adler.
+
+        We now get pull/cancel only once from the source.
+
+        * web-platform-tests/streams/readable-streams/bad-underlying-sources-expected.txt:
+        * web-platform-tests/streams/readable-streams/bad-underlying-sources.dedicatedworker-expected.txt:
+        * web-platform-tests/streams/readable-streams/bad-underlying-sources.serviceworker.https-expected.txt:
+
 2020-06-10  Brent Fulgham  <bfulg...@apple.com>
 
         Improve CSP compliance under PSON

Modified: releases/WebKitGTK/webkit-2.28/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-underlying-sources-expected.txt (264915 => 264916)


--- releases/WebKitGTK/webkit-2.28/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-underlying-sources-expected.txt	2020-07-27 10:48:23 UTC (rev 264915)
+++ releases/WebKitGTK/webkit-2.28/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-underlying-sources-expected.txt	2020-07-27 10:48:31 UTC (rev 264916)
@@ -1,19 +1,11 @@
 
 PASS Underlying source start: throwing getter 
 PASS Underlying source start: throwing method 
-FAIL Underlying source: throwing pull getter (initial pull) assert_throws: constructor should throw function "() => new ReadableStream({
-    get pull() {
-      throw theError;
-    }
-  })" did not throw
+PASS Underlying source: throwing pull getter (initial pull) 
 PASS Underlying source: throwing pull method (initial pull) 
-FAIL Underlying source pull: throwing getter (second pull does not result in a second get) promise_test: Unhandled rejection with value: object "Error: a unique string"
+PASS Underlying source pull: throwing getter (second pull does not result in a second get) 
 PASS Underlying source pull: throwing method (second pull) 
-FAIL Underlying source cancel: throwing getter assert_throws: constructor should throw function "() => new ReadableStream({
-    get cancel() {
-      throw theError;
-    }
-  })" did not throw
+PASS Underlying source cancel: throwing getter 
 PASS Underlying source cancel: throwing method 
 PASS Underlying source: calling enqueue on an empty canceled stream should throw 
 PASS Underlying source: calling enqueue on a non-empty canceled stream should throw 

Modified: releases/WebKitGTK/webkit-2.28/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-underlying-sources.dedicatedworker-expected.txt (264915 => 264916)


--- releases/WebKitGTK/webkit-2.28/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-underlying-sources.dedicatedworker-expected.txt	2020-07-27 10:48:23 UTC (rev 264915)
+++ releases/WebKitGTK/webkit-2.28/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-underlying-sources.dedicatedworker-expected.txt	2020-07-27 10:48:31 UTC (rev 264916)
@@ -1,19 +1,11 @@
 
 PASS Underlying source start: throwing getter 
 PASS Underlying source start: throwing method 
-FAIL Underlying source: throwing pull getter (initial pull) assert_throws: constructor should throw function "() => new ReadableStream({
-    get pull() {
-      throw theError;
-    }
-  })" did not throw
+PASS Underlying source: throwing pull getter (initial pull) 
 PASS Underlying source: throwing pull method (initial pull) 
-FAIL Underlying source pull: throwing getter (second pull does not result in a second get) promise_test: Unhandled rejection with value: object "Error: a unique string"
+PASS Underlying source pull: throwing getter (second pull does not result in a second get) 
 PASS Underlying source pull: throwing method (second pull) 
-FAIL Underlying source cancel: throwing getter assert_throws: constructor should throw function "() => new ReadableStream({
-    get cancel() {
-      throw theError;
-    }
-  })" did not throw
+PASS Underlying source cancel: throwing getter 
 PASS Underlying source cancel: throwing method 
 PASS Underlying source: calling enqueue on an empty canceled stream should throw 
 PASS Underlying source: calling enqueue on a non-empty canceled stream should throw 

Modified: releases/WebKitGTK/webkit-2.28/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-underlying-sources.serviceworker.https-expected.txt (264915 => 264916)


--- releases/WebKitGTK/webkit-2.28/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-underlying-sources.serviceworker.https-expected.txt	2020-07-27 10:48:23 UTC (rev 264915)
+++ releases/WebKitGTK/webkit-2.28/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-underlying-sources.serviceworker.https-expected.txt	2020-07-27 10:48:31 UTC (rev 264916)
@@ -2,19 +2,11 @@
 PASS Service worker test setup 
 PASS Underlying source start: throwing getter 
 PASS Underlying source start: throwing method 
-FAIL Underlying source: throwing pull getter (initial pull) assert_throws: constructor should throw function "() => new ReadableStream({
-    get pull() {
-      throw theError;
-    }
-  })" did not throw
+PASS Underlying source: throwing pull getter (initial pull) 
 PASS Underlying source: throwing pull method (initial pull) 
-FAIL Underlying source pull: throwing getter (second pull does not result in a second get) promise_test: Unhandled rejection with value: object "Error: a unique string"
+PASS Underlying source pull: throwing getter (second pull does not result in a second get) 
 PASS Underlying source pull: throwing method (second pull) 
-FAIL Underlying source cancel: throwing getter assert_throws: constructor should throw function "() => new ReadableStream({
-    get cancel() {
-      throw theError;
-    }
-  })" did not throw
+PASS Underlying source cancel: throwing getter 
 PASS Underlying source cancel: throwing method 
 PASS Underlying source: calling enqueue on an empty canceled stream should throw 
 PASS Underlying source: calling enqueue on a non-empty canceled stream should throw 

Modified: releases/WebKitGTK/webkit-2.28/Source/WebCore/ChangeLog (264915 => 264916)


--- releases/WebKitGTK/webkit-2.28/Source/WebCore/ChangeLog	2020-07-27 10:48:23 UTC (rev 264915)
+++ releases/WebKitGTK/webkit-2.28/Source/WebCore/ChangeLog	2020-07-27 10:48:31 UTC (rev 264916)
@@ -1,3 +1,29 @@
+2020-06-17  Youenn Fablet  <you...@apple.com>
+
+        Make ReadableStream robust against user code
+        https://bugs.webkit.org/show_bug.cgi?id=212915
+        <rdar://problem/64133221>
+
+        Reviewed by Darin Adler.
+
+        Create tee source with private slots instead of public ones.
+        When source has one of this private slot, we directly go to the creation of a ReadableStream.
+        Covered by existing tests.
+
+        * Modules/streams/ReadableStream.js:
+        (initializeReadableStream):
+        * Modules/streams/ReadableStreamInternals.js:
+        (setupReadableStreamDefaultController):
+        (readableStreamTee):
+        (readableStreamDefaultControllerCallPullIfNeeded):
+        (readableStreamDefaultControllerCancel):
+        * Modules/streams/StreamInternals.js:
+        (promiseInvokeOrNoopMethodNoCatch):
+        (promiseInvokeOrNoopNoCatch):
+        (promiseInvokeOrNoopMethod):
+        (promiseInvokeOrNoop):
+        * bindings/js/WebCoreBuiltinNames.h:
+
 2020-06-08  Yusuke Suzuki  <ysuz...@apple.com>
 
         Use usual promise in readableStreamTee

Modified: releases/WebKitGTK/webkit-2.28/Source/WebCore/Modules/streams/ReadableStream.js (264915 => 264916)


--- releases/WebKitGTK/webkit-2.28/Source/WebCore/Modules/streams/ReadableStream.js	2020-07-27 10:48:23 UTC (rev 264915)
+++ releases/WebKitGTK/webkit-2.28/Source/WebCore/Modules/streams/ReadableStream.js	2020-07-27 10:48:31 UTC (rev 264916)
@@ -48,6 +48,13 @@
     // Initialized with null value to enable distinction with undefined case.
     @putByIdDirectPrivate(this, "readableStreamController", null);
 
+    // FIXME: We should introduce https://streams.spec.whatwg.org/#create-readable-stream.
+    // For now, we emulate this with underlyingSource with private properties.
+    if (@getByIdDirectPrivate(underlyingSource, "pull") !== @undefined) {
+        @setupReadableStreamDefaultController(this, underlyingSource, @undefined, 1, @getByIdDirectPrivate(underlyingSource, "start"), @getByIdDirectPrivate(underlyingSource, "pull"), @getByIdDirectPrivate(underlyingSource, "cancel"));
+        return this;
+    }
+
     const type = underlyingSource.type;
     const typeString = @toString(type);
 
@@ -65,7 +72,8 @@
     } else if (type === @undefined) {
         if (strategy.highWaterMark === @undefined)
             strategy.highWaterMark = 1;
-        @putByIdDirectPrivate(this, "readableStreamController", new @ReadableStreamDefaultController(this, underlyingSource, strategy.size, strategy.highWaterMark, @isReadableStream));
+
+        @setupReadableStreamDefaultController(this, underlyingSource, strategy.size, strategy.highWaterMark, underlyingSource.start, underlyingSource.pull, underlyingSource.cancel);
     } else
         @throwRangeError("Invalid type for underlying source");
 

Modified: releases/WebKitGTK/webkit-2.28/Source/WebCore/Modules/streams/ReadableStreamInternals.js (264915 => 264916)


--- releases/WebKitGTK/webkit-2.28/Source/WebCore/Modules/streams/ReadableStreamInternals.js	2020-07-27 10:48:23 UTC (rev 264915)
+++ releases/WebKitGTK/webkit-2.28/Source/WebCore/Modules/streams/ReadableStreamInternals.js	2020-07-27 10:48:31 UTC (rev 264916)
@@ -63,8 +63,26 @@
     @putByIdDirectPrivate(this, "pulling", false);
     @putByIdDirectPrivate(this, "strategy", @validateAndNormalizeQueuingStrategy(size, highWaterMark));
 
-    const controller = this;
-    @promiseInvokeOrNoopNoCatch(underlyingSource, "start", [this]).@then(() => {
+    return this;
+}
+
+// https://streams.spec.whatwg.org/#set-up-readable-stream-default-controller, starting from step 6.
+// The other part is implemented in privateInitializeReadableStreamDefaultController.
+function setupReadableStreamDefaultController(stream, underlyingSource, size, highWaterMark, startMethod, pullMethod, cancelMethod)
+{
+    "use strict";
+    const controller = new @ReadableStreamDefaultController(stream, underlyingSource, size, highWaterMark, @isReadableStream);
+    const startAlgorithm = () => @promiseInvokeOrNoopMethodNoCatch(underlyingSource, startMethod, [controller]);
+    const pullAlgorithm = () => @promiseInvokeOrNoopMethod(underlyingSource, pullMethod, [controller]);
+    const cancelAlgorithm = (reason) => @promiseInvokeOrNoopMethod(underlyingSource, cancelMethod, [reason]);
+
+    @putByIdDirectPrivate(controller, "pullAlgorithm", pullAlgorithm);
+    @putByIdDirectPrivate(controller, "cancelAlgorithm", cancelAlgorithm);
+    @putByIdDirectPrivate(controller, "pull", @readableStreamDefaultControllerPull);
+    @putByIdDirectPrivate(controller, "cancel", @readableStreamDefaultControllerCancel);
+    @putByIdDirectPrivate(stream, "readableStreamController", controller);
+
+    startAlgorithm().@then(() => {
         @putByIdDirectPrivate(controller, "started", true);
         @assert(!@getByIdDirectPrivate(controller, "pulling"));
         @assert(!@getByIdDirectPrivate(controller, "pullAgain"));
@@ -72,12 +90,6 @@
     }, (error) => {
         @readableStreamDefaultControllerError(controller, error);
     });
-
-    @putByIdDirectPrivate(this, "cancel", @readableStreamDefaultControllerCancel);
-
-    @putByIdDirectPrivate(this, "pull", @readableStreamDefaultControllerPull);
-
-    return this;
 }
 
 function readableStreamDefaultControllerError(controller, error)
@@ -141,15 +153,17 @@
 
     const pullFunction = @readableStreamTeePullFunction(teeState, reader, shouldClone);
 
-    const branch1 = new @ReadableStream({
-        "pull": pullFunction,
-        "cancel": @readableStreamTeeBranch1CancelFunction(teeState, stream)
-    });
-    const branch2 = new @ReadableStream({
-        "pull": pullFunction,
-        "cancel": @readableStreamTeeBranch2CancelFunction(teeState, stream)
-    });
+    const branch1Source = { };
+    @putByIdDirectPrivate(branch1Source, "pull", pullFunction);
+    @putByIdDirectPrivate(branch1Source, "cancel", @readableStreamTeeBranch1CancelFunction(teeState, stream));
 
+    const branch2Source = { };
+    @putByIdDirectPrivate(branch2Source, "pull", pullFunction);
+    @putByIdDirectPrivate(branch2Source, "cancel", @readableStreamTeeBranch2CancelFunction(teeState, stream));
+
+    const branch1 = new @ReadableStream(branch1Source);
+    const branch2 = new @ReadableStream(branch2Source);
+
     @getByIdDirectPrivate(reader, "closedPromiseCapability").@promise.@then(@undefined, function(e) {
         if (teeState.closedOrErrored)
             return;
@@ -322,7 +336,7 @@
     @assert(!@getByIdDirectPrivate(controller, "pullAgain"));
     @putByIdDirectPrivate(controller, "pulling", true);
 
-    @promiseInvokeOrNoop(@getByIdDirectPrivate(controller, "underlyingSource"), "pull", [controller]).@then(function() {
+    @getByIdDirectPrivate(controller, "pullAlgorithm").@call(@undefined).@then(function() {
         @putByIdDirectPrivate(controller, "pulling", false);
         if (@getByIdDirectPrivate(controller, "pullAgain")) {
             @putByIdDirectPrivate(controller, "pullAgain", false);
@@ -385,7 +399,7 @@
     "use strict";
 
     @putByIdDirectPrivate(controller, "queue", @newQueue());
-    return @promiseInvokeOrNoop(@getByIdDirectPrivate(controller, "underlyingSource"), "cancel", [reason]);
+    return @getByIdDirectPrivate(controller, "cancelAlgorithm").@call(@undefined, reason);
 }
 
 function readableStreamDefaultControllerPull(controller)

Modified: releases/WebKitGTK/webkit-2.28/Source/WebCore/Modules/streams/StreamInternals.js (264915 => 264916)


--- releases/WebKitGTK/webkit-2.28/Source/WebCore/Modules/streams/StreamInternals.js	2020-07-27 10:48:23 UTC (rev 264915)
+++ releases/WebKitGTK/webkit-2.28/Source/WebCore/Modules/streams/StreamInternals.js	2020-07-27 10:48:31 UTC (rev 264916)
@@ -36,16 +36,34 @@
     return promise;
 }
 
-function promiseInvokeOrNoopNoCatch(object, key, args)
+function promiseInvokeOrNoopMethodNoCatch(object, method, args)
 {
     "use strict";
 
-    const method = object[key];
     if (method === @undefined)
         return @Promise.@resolve();
     return @shieldingPromiseResolve(method.@apply(object, args));
 }
 
+function promiseInvokeOrNoopNoCatch(object, key, args)
+{
+    "use strict";
+
+    return @promiseInvokeOrNoopMethodNoCatch(object, object[key], args);
+}
+
+function promiseInvokeOrNoopMethod(object, method, args)
+{
+    "use strict";
+
+    try {
+        return @promiseInvokeOrNoopMethodNoCatch(object, method, args);
+    }
+    catch(error) {
+        return @Promise.@reject(error);
+    }
+}
+
 function promiseInvokeOrNoop(object, key, args)
 {
     "use strict";
@@ -56,7 +74,6 @@
     catch(error) {
         return @Promise.@reject(error);
     }
-
 }
 
 function promiseInvokeOrFallbackOrNoop(object, key1, args1, key2, args2)

Modified: releases/WebKitGTK/webkit-2.28/Source/WebCore/bindings/js/WebCoreBuiltinNames.h (264915 => 264916)


--- releases/WebKitGTK/webkit-2.28/Source/WebCore/bindings/js/WebCoreBuiltinNames.h	2020-07-27 10:48:23 UTC (rev 264915)
+++ releases/WebKitGTK/webkit-2.28/Source/WebCore/bindings/js/WebCoreBuiltinNames.h	2020-07-27 10:48:31 UTC (rev 264916)
@@ -245,6 +245,7 @@
     macro(byobRequest) \
     macro(caches) \
     macro(cancel) \
+    macro(cancelAlgorithm) \
     macro(cancelIdleCallback) \
     macro(cloneArrayBuffer) \
     macro(close) \
@@ -307,6 +308,7 @@
     macro(privateGetStats) \
     macro(pull) \
     macro(pullAgain) \
+    macro(pullAlgorithm) \
     macro(pulling) \
     macro(queue) \
     macro(queuedAddIceCandidate) \
@@ -329,6 +331,7 @@
     macro(setBodyFromInputRequest) \
     macro(setStatus) \
     macro(showModalDialog) \
+    macro(start) \
     macro(startConsumingStream) \
     macro(started) \
     macro(startedPromise) \
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to