diff --git a/.eslintrc.json b/.eslintrc.json index a03dd436f..9bc877dfd 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -159,6 +159,7 @@ ], "new-parens": "error", "no-bitwise": "off", + "no-buffer-constructor": "error", "no-caller": "error", "no-cond-assign": "error", "no-console": "error", @@ -175,6 +176,13 @@ "no-new-wrappers": "error", "no-redeclare": "error", "no-return-await": "error", + "no-restricted-syntax": [ + "error", + { + "selector": "CallExpression[callee.object.name='Buffer'][callee.property.name='from']", + "message": "Use of Buffer.from is forbidden." + } + ], "no-sequences": "error", "no-shadow": "off", "no-sparse-arrays": "error", diff --git a/lib/id3v2/FrameParser.ts b/lib/id3v2/FrameParser.ts index 2e5ddbc84..1e22483e6 100644 --- a/lib/id3v2/FrameParser.ts +++ b/lib/id3v2/FrameParser.ts @@ -184,7 +184,7 @@ export class FrameParser { pic.description = util.decodeString(uint8Array.slice(offset, fzero), encoding); offset = fzero + nullTerminatorLength; - pic.data = Buffer.from(uint8Array.slice(offset, length)); + pic.data = uint8Array.slice(offset, length); output = pic; } break; diff --git a/lib/id3v2/ID3v2Parser.ts b/lib/id3v2/ID3v2Parser.ts index 27ceafe45..9bafd28e1 100644 --- a/lib/id3v2/ID3v2Parser.ts +++ b/lib/id3v2/ID3v2Parser.ts @@ -30,6 +30,8 @@ interface IFrameHeader { flags?: IFrameFlags; } +const asciiDecoder = new TextDecoder('ascii'); + export class ID3v2Parser { public static removeUnsyncBytes(buffer: Uint8Array): Uint8Array { @@ -204,7 +206,7 @@ export class ID3v2Parser { case 2: header = { - id: Buffer.from(uint8Array.slice(0, 3)).toString('ascii'), + id: asciiDecoder.decode(uint8Array.slice(0, 3)), length: Token.UINT24_BE.get(uint8Array, 3) }; if (!header.id.match(/[A-Z0-9]{3}/g)) { @@ -215,7 +217,7 @@ export class ID3v2Parser { case 3: case 4: header = { - id: Buffer.from(uint8Array.slice(0, 4)).toString('ascii'), + id: asciiDecoder.decode(uint8Array.slice(0, 4)), length: (majorVer === 4 ? UINT32SYNCSAFE : Token.UINT32_BE).get(uint8Array, 4), flags: ID3v2Parser.readFrameFlags(uint8Array.slice(8, 10)) }; diff --git a/lib/mp4/AtomToken.ts b/lib/mp4/AtomToken.ts index 929e9e452..f7ee6dcc0 100644 --- a/lib/mp4/AtomToken.ts +++ b/lib/mp4/AtomToken.ts @@ -323,7 +323,7 @@ export interface IDataAtom { /** * An array of bytes containing the value of the metadata. */ - value: Buffer; + value: Uint8Array; } /** @@ -341,7 +341,7 @@ export class DataAtom implements IGetToken { type: Token.UINT24_BE.get(buf, off + 1) }, locale: Token.UINT24_BE.get(buf, off + 4), - value: Buffer.from(new Token.Uint8ArrayType(this.len - 8).get(buf, off + 8)) + value: new Token.Uint8ArrayType(this.len - 8).get(buf, off + 8) }; } } diff --git a/lib/mp4/MP4Parser.ts b/lib/mp4/MP4Parser.ts index 9fe2e4909..df1272e4e 100644 --- a/lib/mp4/MP4Parser.ts +++ b/lib/mp4/MP4Parser.ts @@ -340,7 +340,7 @@ export class MP4Parser extends BasicParser { break; case 'rate': - const rate = dataAtom.value.toString('ascii'); + const rate = new TextDecoder('ascii').decode(dataAtom.value); await this.addTag(tagKey, rate); break; @@ -351,7 +351,7 @@ export class MP4Parser extends BasicParser { case 1: // UTF-8: Without any count or NULL terminator case 18: // Unknown: Found in m4b in combination with a '©gen' tag - await this.addTag(tagKey, dataAtom.value.toString('utf-8')); + await this.addTag(tagKey, new TextDecoder('utf-8').decode(dataAtom.value)); break; case 13: // JPEG @@ -359,7 +359,7 @@ export class MP4Parser extends BasicParser { break; await this.addTag(tagKey, { format: 'image/jpeg', - data: Buffer.from(dataAtom.value) + data: Uint8Array.from(dataAtom.value) }); break; @@ -368,7 +368,7 @@ export class MP4Parser extends BasicParser { break; await this.addTag(tagKey, { format: 'image/png', - data: Buffer.from(dataAtom.value) + data: Uint8Array.from(dataAtom.value) }); break; @@ -381,15 +381,15 @@ export class MP4Parser extends BasicParser { break; case 65: // An 8-bit signed integer - await this.addTag(tagKey, dataAtom.value.readInt8(0)); + await this.addTag(tagKey, Token.UINT8.get(dataAtom.value,0)); break; case 66: // A big-endian 16-bit signed integer - await this.addTag(tagKey, dataAtom.value.readInt16BE(0)); + await this.addTag(tagKey, Token.UINT16_BE.get(dataAtom.value,0)); break; case 67: // A big-endian 32-bit signed integer - await this.addTag(tagKey, dataAtom.value.readInt32BE(0)); + await this.addTag(tagKey, Token.UINT32_BE.get(dataAtom.value,0)); break; default: diff --git a/lib/musepack/sv7/StreamVersion7.ts b/lib/musepack/sv7/StreamVersion7.ts index 43faf893a..1fd9efb6c 100644 --- a/lib/musepack/sv7/StreamVersion7.ts +++ b/lib/musepack/sv7/StreamVersion7.ts @@ -44,7 +44,7 @@ export const Header: IGetToken = { const header = { // word 0 - signature: Buffer.from(buf).toString('latin1', off, off + 3), + signature: new TextDecoder('latin1').decode(buf.subarray(off, off + 3)), // versionIndex number * 1000 (3.81 = 3810) (remember that 4-byte alignment causes this to take 4-bytes) streamMinorVersion: util.getBitAllignedNumber(buf, off + 3, 0, 4), streamMajorVersion: util.getBitAllignedNumber(buf, off + 3, 4, 4), diff --git a/lib/ogg/OggParser.ts b/lib/ogg/OggParser.ts index 9b415391e..775d70713 100644 --- a/lib/ogg/OggParser.ts +++ b/lib/ogg/OggParser.ts @@ -94,7 +94,7 @@ export class OggParser extends BasicParser { const pageData = await this.tokenizer.readToken(new Token.Uint8ArrayType(segmentTable.totalPageSize)); debug('firstPage=%s, lastPage=%s, continued=%s', header.headerType.firstPage, header.headerType.lastPage, header.headerType.continued); if (header.headerType.firstPage) { - const id = new Token.StringType(7, 'ascii').get(Buffer.from(pageData), 0); + const id = new TextDecoder('ascii').decode(pageData.subarray(0, 7)); switch (id) { case '\x01vorbis': // Ogg/Vorbis debug('Set page consumer to Ogg/Vorbis'); diff --git a/lib/ogg/vorbis/Vorbis.ts b/lib/ogg/vorbis/Vorbis.ts index 2adb00348..dcee4900f 100644 --- a/lib/ogg/vorbis/Vorbis.ts +++ b/lib/ogg/vorbis/Vorbis.ts @@ -61,7 +61,7 @@ export class VorbisPictureToken implements IGetToken { const indexed_color = Token.UINT32_BE.get(buffer, offset += 4); const picDataLen = Token.UINT32_BE.get(buffer, offset += 4); - const data = Buffer.from(buffer.slice(offset += 4, offset + picDataLen)); + const data = Uint8Array.from(buffer.slice(offset += 4, offset + picDataLen)); return { type, diff --git a/lib/ogg/vorbis/VorbisDecoder.ts b/lib/ogg/vorbis/VorbisDecoder.ts index 4aecd5cd7..09613f8aa 100644 --- a/lib/ogg/vorbis/VorbisDecoder.ts +++ b/lib/ogg/vorbis/VorbisDecoder.ts @@ -13,7 +13,7 @@ export class VorbisDecoder { public readStringUtf8(): string { const len = this.readInt32(); - const value = Buffer.from(this.data).toString('utf-8', this.offset, this.offset + len); + const value = new TextDecoder('utf-8').decode(this.data.subarray(this.offset, this.offset + len)); this.offset += len; return value; } diff --git a/test/test-id3v2.4-musicbrainz.ts b/test/test-id3v2.4-musicbrainz.ts index feefdba72..1eaa93d0d 100644 --- a/test/test-id3v2.4-musicbrainz.ts +++ b/test/test-id3v2.4-musicbrainz.ts @@ -129,7 +129,7 @@ it('should MusicBrainz tags with id3v2.4', async () => { assert.deepEqual(native[i++], {id: 'TXXX:originalyear', value: '2004'}, '[\'ID3v2.4\'].\'originalyear'); assert.deepEqual(native[i++], { id: 'UFID', value: { - identifier: Buffer.from([ + identifier: Uint8Array.from([ 0x38, 0x34, 0x38, 0x35, 0x31, 0x31, 0x35, 0x30, 0x2d, 0x61, 0x31, 0x39, 0x36, 0x2d, 0x34, 0x38, 0x66, 0x61, 0x2d, 0x61, 0x64, 0x61, 0x35, 0x2d, 0x31, 0x61, 0x30, 0x31, 0x32, 0x62, 0x31, 0x63, 0x64, 0x39, 0x65, 0x64]), diff --git a/test/test-picard-parsing.ts b/test/test-picard-parsing.ts index 1eff15ab4..a6476938b 100644 --- a/test/test-picard-parsing.ts +++ b/test/test-picard-parsing.ts @@ -334,7 +334,7 @@ describe('Parsing of metadata saved by \'Picard\' in audio files', () => { assert.deepEqual(native.TMED, ['CD'], 'id3v23.TMED: Media type'); assert.deepEqual(native.UFID[0], { owner_identifier: 'http://musicbrainz.org', - identifier: Buffer.from('f151cb94-c909-46a8-ad99-fb77391abfb8', 'ascii') + identifier: new TextEncoder().encode('f151cb94-c909-46a8-ad99-fb77391abfb8') }, 'id3v23.UFID: Unique file identifier'); assert.deepEqual(native.IPLS, [{ @@ -472,7 +472,7 @@ describe('Parsing of metadata saved by \'Picard\' in audio files', () => { assert.deepEqual(id3v24.UFID[0], { owner_identifier: 'http://musicbrainz.org', - identifier: Buffer.from('f151cb94-c909-46a8-ad99-fb77391abfb8', 'ascii') + identifier: new TextEncoder().encode('f151cb94-c909-46a8-ad99-fb77391abfb8') }, 'id3v24.UFID: Unique file identifier'); assert.deepEqual(id3v24['TXXX:ASIN'], ['B005NPEUB2'], 'id3v24.TXXX:ASIN'); diff --git a/test/test-util.ts b/test/test-util.ts index 3a6091ac5..3902e9842 100644 --- a/test/test-util.ts +++ b/test/test-util.ts @@ -80,25 +80,6 @@ describe('shared utility functionality', () => { {fourCC: ' XM ', valid: false} ]; - it('should only accept a valid identifier, otherwise is should throw an error', () => { - for (const data of testData) { - const buf = Buffer.from(data.fourCC, 'ascii'); - - let valid; - let fourCC; - try { - fourCC = FourCcToken.get(buf, 0); - valid = true; - } catch (e) { - valid = false; - } - t.strictEqual(valid, data.valid, `FourCC: ${util.a2hex(data.fourCC)} "${data.fourCC}"`); - if (data.valid) { - t.strictEqual(fourCC, data.fourCC); - } - } - }); - it('should be able to encode FourCC token', () => { const buffer = Buffer.alloc(4); FourCcToken.put(buffer, 0, 'abcd');