Skip to content

Commit

Permalink
fix: check for multiple id3 sections in a file (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonocasey authored Oct 6, 2020
1 parent 9983be8 commit 759a039
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 9 deletions.
31 changes: 22 additions & 9 deletions src/containers.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,37 @@
import {bytesToString, toUint8} from './byte-helpers.js';

export const getId3Offset = function(bytes) {
export const id3Size = function(bytes, offset = 0) {
bytes = toUint8(bytes);

if (bytes.length < 10 || bytesToString(bytes.subarray(0, 3)) !== 'ID3') {
return 0;
}
const returnSize = (bytes[6] << 21) |
(bytes[7] << 14) |
(bytes[8] << 7) |
(bytes[9]);
const flags = bytes[5];
const returnSize = (bytes[offset + 6] << 21) |
(bytes[offset + 7] << 14) |
(bytes[offset + 8] << 7) |
(bytes[offset + 9]);
const flags = bytes[offset + 5];
const footerPresent = (flags & 16) >> 4;

if (footerPresent) {
return returnSize + 20;
}

return returnSize + 10;
};

export const getId3Offset = function(bytes, offset = 0) {
bytes = toUint8(bytes);

if ((bytes.length - offset) < 10 || bytesToString(bytes.subarray(offset, offset + 3)) !== 'ID3') {
return offset;
}

offset += id3Size(bytes, offset);

// recursive check for id3 tags as some files
// have multiple ID3 tag sections even though
// they should not.
return getId3Offset(bytes, offset);
};

export const isLikely = {
aac(bytes) {
const offset = getId3Offset(bytes);
Expand Down
21 changes: 21 additions & 0 deletions test/container.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,29 @@ QUnit.test('should identify known types', function(assert) {
const dataWithId3 = new Uint8Array([].concat(id3Data).concat(testData[type]));
const dataWithId3Footer = new Uint8Array([].concat(id3DataWithFooter).concat(testData[type]));

const recursiveDataWithId3 = new Uint8Array([]
.concat(id3Data)
.concat(id3Data)
.concat(id3Data)
.concat(testData[type]));
const recursiveDataWithId3Footer = new Uint8Array([]
.concat(id3DataWithFooter)
.concat(id3DataWithFooter)
.concat(id3DataWithFooter)
.concat(testData[type]));

const differentId3Sections = new Uint8Array([]
.concat(id3DataWithFooter)
.concat(id3Data)
.concat(id3DataWithFooter)
.concat(id3Data)
.concat(testData[type]));

assert.equal(detectContainerForBytes(dataWithId3), type, `id3 skipped and ${type} detected`);
assert.equal(detectContainerForBytes(dataWithId3Footer), type, `id3 + footer skipped and ${type} detected`);
assert.equal(detectContainerForBytes(recursiveDataWithId3), type, `id3 x3 skipped and ${type} detected`);
assert.equal(detectContainerForBytes(recursiveDataWithId3Footer), type, `id3 + footer x3 skipped and ${type} detected`);
assert.equal(detectContainerForBytes(differentId3Sections), type, `id3 with/without footer skipped and ${type} detected`);
});

const notTs = []
Expand Down

0 comments on commit 759a039

Please sign in to comment.