[whatwg/streams] Various fixes for readable byte streams (#1123)

While working on #1114, we found that `byobRequest.respondWithNewView(newView)` didn't support all the same use cases as a regular `.respond(bytesWritten)` call. In particular:
* `newView` was required to be the same length as the BYOB request's view. This would have required the underlying byte source to always fill *the entire view*. On the other hand, `.respond()` allows responding with fewer bytes *up to the view's length*, which is the desired behavior.
* When the stream is closed, `.respond()` can only be called with `bytesWritten` set to 0. To match this, `.respondWithNewView()` should only be called with an empty view in the closed state.

We now also require the view passed to `.respondWithNewView(newView)` to have the same capacity as the BYOB request's original buffer. Ideally, we would like to assert that the new view's buffer is the "transferred version" of the BYOB request's buffer, but that's not possible yet with the tools currently provided by the ECMAScript specification.

I also found cases where the stream would try to transfer an already transferred buffer. For example, this code crashes the tab in Chrome 92 (error code: `STATUS_ACCESS_VIOLATION`):
```javascript
var rs = new ReadableStream({
    type: 'bytes',
    pull(c) {
        var buffer = c.byobRequest.view.buffer;
        // Detach the buffer.
        postMessage(buffer, '*', [buffer]);
        // Try to enqueue with a new buffer.
        // The stream will try to copy to the pull-into request's view, but it can't because it has lost the buffer.
        c.enqueue(new Uint8Array([42]));
    }
});
var r = rs.getReader({ mode: 'byob' });
await r.read(new Uint8Array(1));
```
I fixed this by requiring the BYOB request's buffer to not be detached when calling `byteStreamController.enqueue()` or `.close()`.

- [ ] At least two implementers are interested (and none opposed):
   * …
   * …
- [ ] [Tests](https://github.com/web-platform-tests/wpt) are written and can be reviewed and commented upon at:
   * …
- [ ] [Implementation bugs](https://github.com/whatwg/meta/blob/main/MAINTAINERS.md#handling-pull-requests) are filed:
   * Chrome: …
   * Firefox: …
   * Safari: …

(See [WHATWG Working Mode: Changes](https://whatwg.org/working-mode#changes) for more details.)

You can view, comment on, or merge this pull request online at:

  https://github.com/whatwg/streams/pull/1123


-- Commit Summary --

  * Throw when trying to enqueue/close after the BYOB request has been detached
  * Fix some links
  * Ensure new view's buffer has same capacity as BYOB request's initial buffer
  * Allow passing a smaller view to BYOBRequest.respondWithNewView
  * Allow passing an empty view to respondWithNewView() in closed state
  * Restrict pull-into descriptor's byte length to be non-zero
  * Fix check to match ReadableByteStreamControllerRespondInReadableState
  * Roll WPT

-- File Changes --

    M index.bs (39)
    M reference-implementation/lib/ReadableByteStreamController-impl.js (16)
    M reference-implementation/lib/ReadableStreamBYOBRequest-impl.js (3)
    M reference-implementation/lib/abstract-ops/readable-streams.js (9)
    M reference-implementation/web-platform-tests (2)

-- Patch Links --

https://github.com/whatwg/streams/pull/1123.patch

https://github.com/whatwg/streams/pull/1123.diff


-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/streams/pull/1123

Received on Friday, 16 April 2021 23:41:30 UTC