diff options
author | Marcos Casagrande <marcoscvp90@gmail.com> | 2023-08-04 13:57:54 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-04 13:57:54 +0200 |
commit | 5311f69bbbd169726330ddae20ce119624b8e8ca (patch) | |
tree | aa1ba4dd870cef0c8a19b040333197cc4b525db4 | |
parent | 53ab6c004ab25020654d3a17bd68472fc5322d48 (diff) |
fix(ext/file): resolve unresolved Promise in Blob.stream (#20039)
This PR fixes some crashing WPT tests due to an unresolved promise.
---
This could be a [stream spec](https://streams.spec.whatwg.org) bug
When `controller.close` is called on a byob stream, there's no cleanup
of pending `readIntoRequests`. The only cleanup of pending
`readIntoRequests` happen when `.byobRequest.respond(0)` is called, it
happens
here:https://github.com/denoland/deno/blob/6ba245fe2570b29e35a4fd296a196a58870b1e3c/ext/web/06_streams.js#L2026
which ends up calling `readIntoRequest.closeSteps(chunk);` in
https://github.com/denoland/deno/blob/6ba245fe2570b29e35a4fd296a196a58870b1e3c/ext/web/06_streams.js#L2070
To reproduce:
```js
async function byobRead() {
const input = [new Uint8Array([8, 241, 48, 123, 151])];
const stream = new ReadableStream({
type: "bytes",
async pull(controller) {
if(input.length === 0) {
controller.close();
// controller.byobRequest.respond(0); // uncomment for fix
return
}
controller.enqueue(input.shift())
},
});
const reader = stream.getReader({ mode: 'byob' });
const r1 = await reader.read(new Uint8Array(64));
console.log(r1);
const r2 = await reader.read(new Uint8Array(64));
console.log(r2);
}
await byobRead();
```
Running the script triggers:
```
error: Top-level await promise never resolved
```
-rw-r--r-- | ext/web/09_file.js | 6 | ||||
-rw-r--r-- | tools/wpt/expectation.json | 16 |
2 files changed, 17 insertions, 5 deletions
diff --git a/ext/web/09_file.js b/ext/web/09_file.js index 79a9c41b2..94981a2f4 100644 --- a/ext/web/09_file.js +++ b/ext/web/09_file.js @@ -366,7 +366,11 @@ class Blob { const { value, done } = await AsyncGeneratorPrototypeNext( partIterator, ); - if (done) return controller.close(); + if (done) { + controller.close(); + controller.byobRequest?.respond(0); + return; + } if (TypedArrayPrototypeGetByteLength(value) > 0) { return controller.enqueue(value); } diff --git a/tools/wpt/expectation.json b/tools/wpt/expectation.json index 19075e224..2eb165dea 100644 --- a/tools/wpt/expectation.json +++ b/tools/wpt/expectation.json @@ -4414,8 +4414,16 @@ "response-consume-empty.any.worker.html": [ "Consume empty FormData response body as text" ], - "response-consume-stream.any.html": false, - "response-consume-stream.any.worker.html": false, + "response-consume-stream.any.html": [ + "Read text response's body as readableStream with mode=byob", + "Read URLSearchParams response's body as readableStream with mode=byob", + "Read array buffer response's body as readableStream with mode=byob" + ], + "response-consume-stream.any.worker.html": [ + "Read text response's body as readableStream with mode=byob", + "Read URLSearchParams response's body as readableStream with mode=byob", + "Read array buffer response's body as readableStream with mode=byob" + ], "response-init-contenttype.any.html": true, "response-init-contenttype.any.worker.html": true, "response-static-json.any.html": true, @@ -5770,8 +5778,8 @@ "Blob-slice-overflow.any.worker.html": true, "Blob-slice.any.html": true, "Blob-slice.any.worker.html": true, - "Blob-stream.any.html": false, - "Blob-stream.any.worker.html": false, + "Blob-stream.any.html": true, + "Blob-stream.any.worker.html": true, "Blob-text.any.html": true, "Blob-text.any.worker.html": true, "Blob-in-worker.worker.html": true, |