- From: Adam Rice <notifications@github.com>
- Date: Tue, 15 Feb 2022 14:16:49 -0800
- To: whatwg/streams <streams@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/streams/issues/1218@github.com>
Consider the following code: ```js promise_test(async () => { let writer; const ws = new WritableStream({ async close() { await flushAsyncEvents(); writer.write(); } }); writer = ws.getWriter(); await writer.close(); }, 'write() during close() should do nothing'); ``` The call to `writer.close()` results in a call to `WritableStreamDefaultControllerProcessClose`, which runs `[[closeAlgorithm]]` which calls into the underlying sink close() method in step 5. This immediately returns, executing step 6. `Perform ! WritableStreamDefaultControllerClearAlgorithms(controller).` On the next microtask, `writer.write()` is called. This results in a call to `WritableStreamDefaultWriterWrite` which on step 4 calls `WritableStreamDefaultControllerGetChunkSize`. This runs `controller.[[strategySizeAlgorithm]]` which was set to undefined in `WritableStreamDefaultControllerClearAlgorithms`. The reference implementation doesn't crash. Instead, it catches the 'undefined is not a function' error: ```js try { return controller._strategySizeAlgorithm(chunk); } catch (chunkSizeE) { WritableStreamDefaultControllerErrorIfNeeded(controller, chunkSizeE); return 1; } ``` This seems like cheating. Blink's implementation [explicitly checks if `[[strategySize]]` is undefined](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/streams/writable_stream_default_controller.cc?q=file:third_party%2Fblink%2Frenderer%2Fcore%2Fstreams%2Fwritable_stream_default_controller.cc%20GetChunkSize&ss=chromium%2Fchromium%2Fsrc). It only crashes when compiled with debugging checks. I don't recall why I included a check for undefined there. It also seems like cheating, since it's nowhere in the standard. I think the correct fix is not to call `WritableStreamDefaultControllerClearAlgorithms` until after the promise returned by `[[closeAlgorithm]]` resolves or rejects. I don't recall why I didn't do that originally. The same also applies to `[[abortAlgorithm]]`. What do you think? -- Reply to this email directly or view it on GitHub: https://github.com/whatwg/streams/issues/1218 You are receiving this because you are subscribed to this thread. Message ID: <whatwg/streams/issues/1218@github.com>
Received on Tuesday, 15 February 2022 22:17:02 UTC