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

Commit pull-into descriptors after filling from queue #1326

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

MattiasBuelens
Copy link
Collaborator

@MattiasBuelens MattiasBuelens commented Sep 10, 2024

In Chromium bug #339877167, it was discovered that a user could run JavaScript code synchronously during ReadableStreamFulfillReadIntoRequest by patching Object.prototype.then, and use this gadget to break some invariants within ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue.

To prevent this, this PR postpones all calls to ReadableByteStreamControllerCommitPullIntoDescriptor until after all pull-into descriptors have been filled up by ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue. This way, we won't trigger any patched then() method until the stream is in a stable state.

(See WHATWG Working Mode: Changes for more details.)


Preview | Diff

Comment on lines 1451 to 1457
if (SafeCopyDataBlockBytes(pullIntoDescriptor.buffer, destStart, headOfQueue.buffer, headOfQueue.byteOffset,
bytesToCopy) === false) {
// This should never happen. Please report an issue if it does! https://github.com/whatwg/streams/issues
const e = new TypeError('Invalid buffer');
ReadableByteStreamControllerError(controller, e);
return false;
}
Copy link
Collaborator Author

@MattiasBuelens MattiasBuelens Sep 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This SafeCopyDataBlockBytes check should always return true, so we can't write a test to check if an implementation correctly handles the case where it's false. That said, this check is our last chance to prevent a potential memory corruption bug.

Is it better to have a bit of untestable code here, or to only keep it as an assertion and hope that we don't break this again in the future? @domenic @saschanaz

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My preference is an assertion. Perhaps in the spec it's an assertion with a big <p class="warning"> suggesting that implementers really might want to consider crashing if the assertions somehow gets violated?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it to an assertion with a big warning.

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

Successfully merging this pull request may close these issues.

2 participants