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

WritableStreamDefaultController [[strategySizeAlgorithm]] called after being set to undefined #1218

Open
ricea opened this issue Feb 15, 2022 · 2 comments

Comments

@ricea
Copy link
Collaborator

ricea commented Feb 15, 2022

Consider the following code:

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:

  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. 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?

@domenic
Copy link
Member

domenic commented Feb 15, 2022

Looking at the call sites for WritableStreamDefaultControllerClearAlgorithms and I can't really see any rhyme or reason behind them. I'd expect them to happen whenever we set [[state]] to "errored" (maybe "erroring"?) and "closed".

Patching the immediate problem by moving that particular case later might be reasonable, but I wonder if we should do a more comprehensive reform of when they are cleared.

@ricea
Copy link
Collaborator Author

ricea commented Feb 15, 2022

The issue is not urgent (at least for Blink), so we can take the time to do it properly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants