Skip to content

Node: Fix the buffer builder being left unusable - #1999

Closed
jmillan wants to merge 2 commits into
v3from
fix_buffer_builder_unusable
Closed

jmillan wants to merge 2 commits into
v3from
fix_buffer_builder_unusable

Conversation

@jmillan

@jmillan jmillan commented Oct 16, 2026

Copy link
Copy Markdown
Member

Basically clean the buffer builder at the beginning of message creation rather than at the end. In order to cleanup the wrong state left by a previous message construction.

@jmillan
jmillan requested a review from ibc October 16, 2026 14:08

@ibc ibc left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

As commented above I'd prefer if we clean the builder upon failure rather than on next usage.

Also, some kinda related issue:

In stats it could now happen that some "bitrate" field is super big so it becomes automatically a BigInt during the FBS to JS conversion (automatically). The problem is that the application usually uses JSON.stringify(stats) and such a function will fail if any of the json fields is a BigInt.

It's unlikely that we can generate stats with bitrate fields bigger than the biggest normal number supported in Node/JS, because it would literally be 9 Tera bytes per second which is crazy. But perhaps we should always invoke Number(fbsBitrateValue) when converting from FBS to JS just in case.

Comment thread node/src/Channel.ts
* serialization (which would otherwise break every future message).
*/
get bufferBuilder(): flatbuffers.Builder {
this.#bufferBuilder.clear();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't love this solution because it basically means that, in case of corrupted buffer, we leave it that way until the next time we need to use the buffer.

Comment thread node/src/Channel.ts
);
}

// If there is no body then the buffer builder holds nothing we need, so

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is also post-defensive approach that we are supposed to hate.

Comment thread node/src/ortc.ts
// maxBitrate is optional, it can be a number or a bigint.
const maxBitrate: number | bigint | undefined = encoding.maxBitrate;

if (!maxBitrate) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is not valid since 0 is a valid value but it enters this condition. It works by accident but this solution is not valid for other similar cases such as transport.setMaxIncomingBitrate(bitrate) where 0 means "no limit".


// Add max bitrate.
if (encoding.maxBitrate !== undefined) {
if (encoding.maxBitrate) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Again this condition breaks the valid case of value 0.

@ibc

ibc commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

Also, same problem may happen in all methods such as transport.setMax/MinIncoming/OutgoingBitrate().

And there the conditions/checks written in this PR for encoding.maxBitrate are invalid as said above. I would ask to improve them here as well because 0 is a valid value and it's not "lack of value".

@jmillan

jmillan commented Oct 16, 2026

Copy link
Copy Markdown
Member Author

As commented above I'd prefer if we clean the builder upon failure rather than on next usage.

This would mean filling the codebase with try/catches everywhere just to clean the buffer builder. The error came because the the value was not validated by us correctly. It was a bug on our end. And by cleaning up the buffer before, and not later (we just moved the call to clear() from the end to the beginning) we make totally sure that even if we introduce a new bug, it will not affect other messages, hence, it will be isolated.

@ibc

ibc commented Oct 16, 2026

Copy link
Copy Markdown
Member

As commented above I'd prefer if we clean the builder upon failure rather than on next usage.

This would mean filling the codebase with try/catches everywhere just to clean the buffer builder. The error came because the the value was not validated by us correctly. It was a bug on our end. And by cleaning up the buffer before, and not later (we just moved the call to clear() from the end to the beginning) we make totally sure that even if we introduce a new bug, it will not affect other messages, hence, it will be isolated.

Ok I but that. But my other concerns are real and valid IMHO.

@ibc

ibc commented Oct 17, 2026

Copy link
Copy Markdown
Member

Some of the tests in test-Producer.ts added in this PR are wrong. They throw an expected TypeError but not due to the value of encoding.maxBitrate but because they pass an empty codecs array.

@ibc ibc closed this Oct 17, 2026
@ibc
ibc deleted the fix_buffer_builder_unusable branch October 17, 2026 13:28
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