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

fix: prevent skipping frames on garbage adts data #390

Merged
merged 7 commits into from
Jun 30, 2021

Conversation

brandonocasey
Copy link
Contributor

@brandonocasey brandonocasey commented Jun 29, 2021

Right now we run into an issue if adts contains data between sync words that is not part of a frame.

Example
We have an adts file where bytes 0-5 are garbage, and after that the file is like normal. This is what would happen right now:

  1. bytes 0-5 are garbage so they fail the syncword check and i is now incremented up to 5.
  2. We parse that frame successfully as 400 bytes long.
  3. Then we remove those 400 bytes from the front of the buffer using subarray, but we do not reset i to 0
  4. On the next loop we check buffer[i] for a syncword but i is still 5 so we skip everything else in the buffer until the next syncword and further aggravate the problem by incrementing i some more.

}

// remove processed bytes from the buffer.
buffer = buffer.subarray(i);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

remove the bytes that we processed from the buffer.

@@ -64,7 +64,7 @@ AdtsStream = function(handlePartialSegments) {

// Prepend any data in the buffer to the input data so that we can parse
// aac frames the cross a PES packet boundary
if (buffer) {
if (buffer && buffer.length) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Buffer is no longer set to undefined if we don't have bytes left, I was torn on initializing it to an empty uint8 array and always concating with buffer to make all of this code simpler.

// we use i + 3 here because we want to be able to parse the frame length
// from the header. If we don't have enough bytes to do that, than we
// definitely won't have a full frame.
while ((i + 3) < buffer.length) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Since we use i + 5 in determining frameLength below (and i + 6 below that), wouldn't we require at least that much?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

you're right, I only looked at the first byte that it asks for, I will update this.

lib/codecs/adts.js Show resolved Hide resolved
return;
// If we don't have enough data to actually finish this ADTS frame,
// then we have to wait for more data
if ((buffer.byteLength - i) < frameLength) {
Copy link
Contributor

Choose a reason for hiding this comment

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

We should probably move this check up to just after determining the frame length (before the sample count) to prevent errors addressing i + 6

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed the while loop condition to i + 7 so that we won't even run the loop if we don't have enough bytes. That way and we can keep all the parsing logic together.

lib/codecs/adts.js Show resolved Hide resolved
lib/codecs/adts.js Outdated Show resolved Hide resolved
Co-authored-by: Garrett Singer <gesinger@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants