From be7c70b0406533dbdba2e0713d0776cfacc69975 Mon Sep 17 00:00:00 2001 From: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com> Date: Tue, 6 Feb 2024 14:14:36 -0800 Subject: [PATCH] fix: lint passes, removed dead code --- src/buffer-tokenizer.ts | 2 +- src/core.js | 2 +- src/types.ts | 303 ---------------------------------------- src/util.js | 40 ------ src/util.ts | 41 ++++++ test.js | 26 ++-- test/file-type.spec.ts | 15 +- 7 files changed, 65 insertions(+), 364 deletions(-) delete mode 100644 src/util.js create mode 100644 src/util.ts diff --git a/src/buffer-tokenizer.ts b/src/buffer-tokenizer.ts index 218207ca..7547f450 100644 --- a/src/buffer-tokenizer.ts +++ b/src/buffer-tokenizer.ts @@ -46,7 +46,7 @@ export class BufferTokenizer extends AbstractTokenizer { const normOptions = this.normalizeOptions(uint8Array, options) const bytes2read = Math.min(this.uint8Array.length - normOptions.position, normOptions.length) - if ((!normOptions.mayBeLess) && bytes2read < normOptions.length) { + if (normOptions.mayBeLess !== true && bytes2read < normOptions.length) { throw new EndOfStreamError() } else { uint8Array.set(this.uint8Array.subarray(normOptions.position, normOptions.position + bytes2read), normOptions.offset) diff --git a/src/core.js b/src/core.js index bd956f51..b5139397 100644 --- a/src/core.js +++ b/src/core.js @@ -154,6 +154,7 @@ export class FileTypeParser { return this.check(stringToBytes(header), options) } + // eslint-disable-next-line complexity async parse (tokenizer) { this.buffer = alloc(minimumBytes) @@ -1700,4 +1701,3 @@ export class FileTypeParser { // export async function fileTypeStream(readableStream, options = {}) { // return new FileTypeParser().toDetectionStream(readableStream, options); // } - diff --git a/src/types.ts b/src/types.ts index c30a9c51..8b33b96d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,312 +1,9 @@ -// export type FileExtension = -// | 'jpg' -// | 'png' -// | 'apng' -// | 'gif' -// | 'webp' -// | 'flif' -// | 'xcf' -// | 'cr2' -// | 'cr3' -// | 'orf' -// | 'arw' -// | 'dng' -// | 'nef' -// | 'rw2' -// | 'raf' -// | 'tif' -// | 'bmp' -// | 'icns' -// | 'jxr' -// | 'psd' -// | 'indd' -// | 'zip' -// | 'tar' -// | 'rar' -// | 'gz' -// | 'bz2' -// | '7z' -// | 'dmg' -// | 'mp4' -// | 'mid' -// | 'mkv' -// | 'webm' -// | 'mov' -// | 'avi' -// | 'mpg' -// | 'mp2' -// | 'mp3' -// | 'm4a' -// | 'ogg' -// | 'opus' -// | 'flac' -// | 'wav' -// | 'qcp' -// | 'amr' -// | 'pdf' -// | 'epub' -// | 'mobi' -// | 'elf' -// | 'macho' -// | 'exe' -// | 'swf' -// | 'rtf' -// | 'woff' -// | 'woff2' -// | 'eot' -// | 'ttf' -// | 'otf' -// | 'ico' -// | 'flv' -// | 'ps' -// | 'xz' -// | 'sqlite' -// | 'nes' -// | 'crx' -// | 'xpi' -// | 'cab' -// | 'deb' -// | 'ar' -// | 'rpm' -// | 'Z' -// | 'lz' -// | 'cfb' -// | 'mxf' -// | 'mts' -// | 'wasm' -// | 'blend' -// | 'bpg' -// | 'docx' -// | 'pptx' -// | 'xlsx' -// | '3gp' -// | '3g2' -// | 'j2c' -// | 'jp2' -// | 'jpm' -// | 'jpx' -// | 'mj2' -// | 'aif' -// | 'odt' -// | 'ods' -// | 'odp' -// | 'xml' -// | 'heic' -// | 'cur' -// | 'ktx' -// | 'ape' -// | 'wv' -// | 'asf' -// | 'dcm' -// | 'mpc' -// | 'ics' -// | 'glb' -// | 'pcap' -// | 'dsf' -// | 'lnk' -// | 'alias' -// | 'voc' -// | 'ac3' -// | 'm4b' -// | 'm4p' -// | 'm4v' -// | 'f4a' -// | 'f4b' -// | 'f4p' -// | 'f4v' -// | 'mie' -// | 'ogv' -// | 'ogm' -// | 'oga' -// | 'spx' -// | 'ogx' -// | 'arrow' -// | 'shp' -// | 'aac' -// | 'mp1' -// | 'it' -// | 's3m' -// | 'xm' -// | 'ai' -// | 'skp' -// | 'avif' -// | 'eps' -// | 'lzh' -// | 'pgp' -// | 'asar' -// | 'stl' -// | 'chm' -// | '3mf' -// | 'zst' -// | 'jxl' -// | 'vcf' -// | 'jls' -// | 'pst' -// | 'dwg' -// | 'parquet' -// | 'class' -// | 'arj' -// | 'cpio' -// | 'ace' -// | 'avro' -// | 'icc' -// | 'fbx' - import type { extensions, mimeTypes } from './supported.js' export type FileExtension = (typeof extensions)[number] export type MimeType = (typeof mimeTypes)[number] -// export type MimeType = -// | 'image/jpeg' -// | 'image/png' -// | 'image/gif' -// | 'image/webp' -// | 'image/flif' -// | 'image/x-xcf' -// | 'image/x-canon-cr2' -// | 'image/x-canon-cr3' -// | 'image/tiff' -// | 'image/bmp' -// | 'image/icns' -// | 'image/vnd.ms-photo' -// | 'image/vnd.adobe.photoshop' -// | 'application/x-indesign' -// | 'application/epub+zip' -// | 'application/x-xpinstall' -// | 'application/vnd.oasis.opendocument.text' -// | 'application/vnd.oasis.opendocument.spreadsheet' -// | 'application/vnd.oasis.opendocument.presentation' -// | 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' -// | 'application/vnd.openxmlformats-officedocument.presentationml.presentation' -// | 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' -// | 'application/zip' -// | 'application/x-tar' -// | 'application/x-rar-compressed' -// | 'application/gzip' -// | 'application/x-bzip2' -// | 'application/x-7z-compressed' -// | 'application/x-apple-diskimage' -// | 'video/mp4' -// | 'audio/midi' -// | 'video/x-matroska' -// | 'video/webm' -// | 'video/quicktime' -// | 'video/vnd.avi' -// | 'audio/wav' -// | 'audio/qcelp' -// | 'audio/x-ms-asf' -// | 'video/x-ms-asf' -// | 'application/vnd.ms-asf' -// | 'video/mpeg' -// | 'video/3gpp' -// | 'audio/mpeg' -// | 'audio/mp4' // RFC 4337 -// | 'audio/opus' -// | 'video/ogg' -// | 'audio/ogg' -// | 'application/ogg' -// | 'audio/x-flac' -// | 'audio/ape' -// | 'audio/wavpack' -// | 'audio/amr' -// | 'application/pdf' -// | 'application/x-elf' -// | 'application/x-mach-binary' -// | 'application/x-msdownload' -// | 'application/x-shockwave-flash' -// | 'application/rtf' -// | 'application/wasm' -// | 'font/woff' -// | 'font/woff2' -// | 'application/vnd.ms-fontobject' -// | 'font/ttf' -// | 'font/otf' -// | 'image/x-icon' -// | 'video/x-flv' -// | 'application/postscript' -// | 'application/eps' -// | 'application/x-xz' -// | 'application/x-sqlite3' -// | 'application/x-nintendo-nes-rom' -// | 'application/x-google-chrome-extension' -// | 'application/vnd.ms-cab-compressed' -// | 'application/x-deb' -// | 'application/x-unix-archive' -// | 'application/x-rpm' -// | 'application/x-compress' -// | 'application/x-lzip' -// | 'application/x-cfb' -// | 'application/x-mie' -// | 'application/x-apache-arrow' -// | 'application/mxf' -// | 'video/mp2t' -// | 'application/x-blender' -// | 'image/bpg' -// | 'image/j2c' -// | 'image/jp2' -// | 'image/jpx' -// | 'image/jpm' -// | 'image/mj2' -// | 'audio/aiff' -// | 'application/xml' -// | 'application/x-mobipocket-ebook' -// | 'image/heif' -// | 'image/heif-sequence' -// | 'image/heic' -// | 'image/heic-sequence' -// | 'image/ktx' -// | 'application/dicom' -// | 'audio/x-musepack' -// | 'text/calendar' -// | 'text/vcard' -// | 'model/gltf-binary' -// | 'application/vnd.tcpdump.pcap' -// | 'audio/x-dsf' // Non-standard -// | 'application/x.ms.shortcut' // Invented by us -// | 'application/x.apple.alias' // Invented by us -// | 'audio/x-voc' -// | 'audio/vnd.dolby.dd-raw' -// | 'audio/x-m4a' -// | 'image/apng' -// | 'image/x-olympus-orf' -// | 'image/x-sony-arw' -// | 'image/x-adobe-dng' -// | 'image/x-nikon-nef' -// | 'image/x-panasonic-rw2' -// | 'image/x-fujifilm-raf' -// | 'video/x-m4v' -// | 'video/3gpp2' -// | 'application/x-esri-shape' -// | 'audio/aac' -// | 'audio/x-it' -// | 'audio/x-s3m' -// | 'audio/x-xm' -// | 'video/MP1S' -// | 'video/MP2P' -// | 'application/vnd.sketchup.skp' -// | 'image/avif' -// | 'application/x-lzh-compressed' -// | 'application/pgp-encrypted' -// | 'application/x-asar' -// | 'model/stl' -// | 'application/vnd.ms-htmlhelp' -// | 'model/3mf' -// | 'image/jxl' -// | 'application/zstd' -// | 'image/jls' -// | 'application/vnd.ms-outlook' -// | 'image/vnd.dwg' -// | 'application/x-parquet' -// | 'application/java-vm' -// | 'application/x-arj' -// | 'application/x-cpio' -// | 'application/x-ace-compressed' -// | 'application/avro' -// | 'application/vnd.iccprofile' -// | 'application/x.autodesk.fbx' - export interface FileTypeResult { /** One of the supported [file types](https://github.com/sindresorhus/file-type#supported-file-types). diff --git a/src/util.js b/src/util.js deleted file mode 100644 index 3d351b6c..00000000 --- a/src/util.js +++ /dev/null @@ -1,40 +0,0 @@ -import { bufferToString } from './buffer-dataview-tools.js' - -export function stringToBytes (string) { - return [...string].map(character => character.charCodeAt(0)) -} - -/** -Checks whether the TAR checksum is valid. - -@param {Uint8Array} buffer - The TAR header `[offset ... offset + 512]`. -@param {number} offset - TAR header offset. -@returns {boolean} `true` if the TAR checksum is valid, otherwise `false`. - */ -export function tarHeaderChecksumMatches (buffer, offset = 0) { - const readSum = Number.parseInt(bufferToString(buffer, 'utf8', 148, 154).replace(/\0.*$/, '').trim(), 8) // Read sum in header - if (Number.isNaN(readSum)) { - return false - } - - let sum = 8 * 0x20 // Initialize signed bit sum - - for (let index = offset; index < offset + 148; index++) { - sum += buffer[index] - } - - for (let index = offset + 156; index < offset + 512; index++) { - sum += buffer[index] - } - - return readSum === sum -} - -/** -ID3 UINT32 sync-safe tokenizer token. -28 bits (representing up to 256MB) integer, the msb is 0 to avoid "false syncsignals". - */ -export const uint32SyncSafeToken = { - get: (buffer, offset) => (buffer[offset + 3] & 0x7F) | ((buffer[offset + 2]) << 7) | ((buffer[offset + 1]) << 14) | ((buffer[offset]) << 21), - len: 4 -} diff --git a/src/util.ts b/src/util.ts new file mode 100644 index 00000000..e4803467 --- /dev/null +++ b/src/util.ts @@ -0,0 +1,41 @@ +import { bufferToString } from './buffer-dataview-tools.js' + +export function stringToBytes (string: string): number[] { + return [...string].map((character) => character.charCodeAt(0)) +} + +/** + * Checks whether the TAR checksum is valid. + * + * @param buffer - The TAR header `[offset ... offset + 512]`. + * @param offset - TAR header offset. + * + * @returns `true` if the TAR checksum is valid, otherwise `false`. + */ +export function tarHeaderChecksumMatches (buffer: Uint8Array, offset: number = 0): boolean { + const readSum = Number.parseInt(bufferToString(buffer, 'utf8', 148, 154).replace(/\0.*$/, '').trim(), 8) // Read sum in header + if (Number.isNaN(readSum)) { + return false + } + + let sum = 8 * 0x20 // Initialize signed bit sum + + for (let index = offset; index < offset + 148; index++) { + sum += buffer[index] + } + + for (let index = offset + 156; index < offset + 512; index++) { + sum += buffer[index] + } + + return readSum === sum +} + +/** + * ID3 UINT32 sync-safe tokenizer token. + * 28 bits (representing up to 256MB) integer, the msb is 0 to avoid "false syncsignals". + */ +export const uint32SyncSafeToken = { + get: (buffer: Uint32Array, offset: number) => (buffer[offset + 3] & 0x7F) | ((buffer[offset + 2]) << 7) | ((buffer[offset + 1]) << 14) | ((buffer[offset]) << 21), + len: 4 +} diff --git a/test.js b/test.js index dafd79e8..313c83d9 100644 --- a/test.js +++ b/test.js @@ -2,7 +2,7 @@ import { Buffer } from 'node:buffer' import fs from 'node:fs' import path from 'node:path' -import stream from 'node:stream' +// import stream from 'node:stream' import { fileURLToPath } from 'node:url' import test from 'ava' import { Parser as ReadmeParser } from 'commonmark' @@ -605,15 +605,15 @@ test('validate the repo has all extensions and mimes in sync', t => { } }) -class BufferedStream extends stream.Readable { - constructor (buffer) { - super() - this.push(buffer) - this.push(null) - } +// class BufferedStream extends stream.Readable { +// constructor (buffer) { +// super() +// this.push(buffer) +// this.push(null) +// } - _read () {} -} +// _read () {} +// } test('odd file sizes', async t => { const oddFileSizes = [1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 255, 256, 257, 511, 512, 513] @@ -679,10 +679,10 @@ const unicornDetector = async tokenizer => { const mockPngDetector = _tokenizer => ({ ext: 'mockPng', mime: 'image/mockPng' }) -const tokenizerPositionChanger = tokenizer => { - const buffer = Buffer.alloc(1) - tokenizer.readBuffer(buffer, { length: 1, mayBeLess: true }) -} +// const tokenizerPositionChanger = tokenizer => { +// const buffer = Buffer.alloc(1) +// tokenizer.readBuffer(buffer, { length: 1, mayBeLess: true }) +// } test('fileTypeFromBlob should detect custom file type "unicorn" using custom detectors', async t => { // Set up the "unicorn" file content diff --git a/test/file-type.spec.ts b/test/file-type.spec.ts index d0c53531..d3566877 100644 --- a/test/file-type.spec.ts +++ b/test/file-type.spec.ts @@ -5,7 +5,8 @@ import { fileTypeFromBuffer, FileTypeParser, supportedExtensions, - supportedMimeTypes + supportedMimeTypes, + type FileTypeResult } from '../src/index.js' import { getFixtureDataUint8Array } from './get-fixture-data.js' @@ -255,7 +256,7 @@ const failingFixture = new Set([ 'fixture-password-protected' ]) -async function checkBufferLike (type, bufferLike) { +async function checkBufferLike (type, bufferLike): Promise { const { ext, mime } = await fileTypeFromBuffer(bufferLike) ?? {} expect(ext).to.equal(type) expect(typeof mime).to.equal('string') @@ -279,7 +280,7 @@ async function checkBufferLike (type, bufferLike) { // return checkFile(t, ext, file); // } -async function testFromBuffer (ext: string, name?: string) { +async function testFromBuffer (ext: string, name?: string): Promise { const fixtureName = `${(name ?? 'fixture')}.${ext}` const chunk = await getFixtureDataUint8Array(fixtureName) @@ -296,7 +297,7 @@ async function testFromBuffer (ext: string, name?: string) { // await checkBlobLike(t, ext, chunk) // } -async function testFalsePositive (ext, name) { +async function testFalsePositive (ext, name): Promise { const chunk = await getFixtureDataUint8Array(`${name}.${ext}`) await expect(fileTypeFromBuffer(chunk)).to.eventually.be(undefined) @@ -478,18 +479,20 @@ it('corrupt MKV throws', async () => { }) // Create a custom detector for the just made up "unicorn" file type -const unicornDetector = async tokenizer => { +async function unicornDetector (tokenizer): Promise { const unicornHeader = [85, 78, 73, 67, 79, 82, 78] // "UNICORN" as decimal string const buffer = alloc(7) await tokenizer.peekBuffer(buffer, { length: unicornHeader.length, mayBeLess: true }) if (unicornHeader.every((value, index) => value === buffer[index])) { + // @ts-expect-error - purposefully invalid return return { ext: 'unicorn', mime: 'application/unicorn' } } return undefined } -const mockPngDetector = _tokenizer => ({ ext: 'mockPng', mime: 'image/mockPng' }) +// @ts-expect-error - purposefully invalid return +const mockPngDetector = (_tokenizer: unknown): FileTypeResult => ({ ext: 'mockPng', mime: 'image/mockPng' }) // const tokenizerPositionChanger = tokenizer => { // const buffer = Buffer.alloc(1)