From 8c16d586114dc9156386f0b4bdc6c42d7a0e31fb Mon Sep 17 00:00:00 2001 From: Ziggy Jonsson <ziggy.jonsson.nyc@gmail.com> Date: Sun, 12 May 2024 09:15:19 -0400 Subject: [PATCH] fix js errors --- .github/workflows/test.yml | 1 + .gitignore | 1 - jsconfig.json | 4 ++-- lib/Decrypt.js | 7 +++++-- lib/NoopStream.js | 18 ++++++++---------- lib/extract.js | 1 + lib/parse.js | 30 ++++++++++++++++++++---------- lib/parseExtraField.js | 4 +--- lib/parseOne.js | 6 +++--- package.json | 3 ++- test/compressed-crx.js | 8 +++++--- test/office-files.js | 4 ++-- test/streamSingleEntry.js | 2 +- test/uncompressed.js | 4 ++-- 14 files changed, 53 insertions(+), 40 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index eefdaf4..1fd3b41 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,6 +19,7 @@ jobs: node-version: 18.x - run: npm install - run: npx eslint . + - run: npx tsc -p jsconfig.json test: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index ed57018..97223ba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ /.idea /node_modules -/test.js /.nyc_output/ /coverage/ .tap/ diff --git a/jsconfig.json b/jsconfig.json index 1c2fef5..e7d635f 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -3,11 +3,11 @@ "checkJs": true, "target": "ES2022", "moduleResolution":"node", - "types": ["node"] + "types": ["node"], + "maxNodeModuleJsDepth": 0, }, "exclude": [ "node_modules", - "test", "coverage" ] } \ No newline at end of file diff --git a/lib/Decrypt.js b/lib/Decrypt.js index 447d8af..ec4fb0a 100644 --- a/lib/Decrypt.js +++ b/lib/Decrypt.js @@ -21,7 +21,7 @@ function crc(ch, crc) { if (ch.charCodeAt) ch = ch.charCodeAt(0); - + //@ts-ignore return (bigInt(crc).shiftRight(8).and(0xffffff)).xor(table[bigInt(crc).xor(ch).and(0xff)]).value; } @@ -36,7 +36,9 @@ function Decrypt() { Decrypt.prototype.update = function(h) { this.key0 = crc(h, this.key0); + //@ts-ignore this.key1 = bigInt(this.key0).and(255).and(4294967295).add(this.key1); + //@ts-ignore this.key1 = bigInt(this.key1).multiply(134775813).add(1).and(4294967295).value; this.key2 = crc(bigInt(this.key1).shiftRight(24).and(255), this.key2); }; @@ -44,13 +46,14 @@ Decrypt.prototype.update = function(h) { Decrypt.prototype.decryptByte = function(c) { const k = bigInt(this.key2).or(2); + //@ts-ignore c = c ^ bigInt(k).multiply(bigInt(k^1)).shiftRight(8).and(255); this.update(c); return c; }; Decrypt.prototype.stream = function() { - const stream = Stream.Transform(), + const stream = new Stream.Transform(), self = this; stream._transform = function(d, e, cb) { diff --git a/lib/NoopStream.js b/lib/NoopStream.js index 98c05f8..d28dfc2 100644 --- a/lib/NoopStream.js +++ b/lib/NoopStream.js @@ -1,14 +1,12 @@ const Stream = require('stream'); -const util = require('util'); -function NoopStream() { - if (!(this instanceof NoopStream)) { - return new NoopStream(); - } - Stream.Transform.call(this); +class NoopStream extends Stream.Transform { + _transform(d, e, cb) { cb() ;}; + promise() { + return new Promise((resolve, reject) => { + this.on('finish', resolve); + this.on('error', reject); + }); + }; } -util.inherits(NoopStream, Stream.Transform); - -NoopStream.prototype._transform = function(d, e, cb) { cb() ;}; - module.exports = NoopStream; \ No newline at end of file diff --git a/lib/extract.js b/lib/extract.js index 31d725a..8100c34 100644 --- a/lib/extract.js +++ b/lib/extract.js @@ -1,3 +1,4 @@ +//@ts-nocheck module.exports = Extract; const Parse = require('./parse'); diff --git a/lib/parse.js b/lib/parse.js index 1b35cf7..4f14015 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -11,7 +11,23 @@ const parseBuffer = require('./parseBuffer'); const endDirectorySignature = Buffer.alloc(4); endDirectorySignature.writeUInt32LE(0x06054b50, 0); +class Entry extends Stream.PassThrough{ + autodrain; + buffer; + path; + props; + CSSFontFeatureValuesRule; + type; + extra; + size; + vars; + __autodraining; +} + + class Parse extends PullStream { + reachedCD; + crxHeader; constructor(opts) { super(opts || { verbose: false }); const self = this; @@ -105,18 +121,12 @@ class Parse extends PullStream { return self.pull(vars.fileNameLength).then(function(fileNameBuffer) { const fileName = fileNameBuffer.toString('utf8'); - const entry = Stream.PassThrough(); + const entry = new Entry(); let __autodraining = false; entry.autodrain = function() { __autodraining = true; - const draining = entry.pipe(NoopStream()); - draining.promise = function() { - return new Promise(function(resolve, reject) { - draining.on('finish', resolve); - draining.on('error', reject); - }); - }; + const draining = entry.pipe(new NoopStream()); return draining; }; @@ -155,7 +165,7 @@ class Parse extends PullStream { self.push(entry); } else { self.emit('entry', entry); - + //@ts-ignore if (self._readableState.pipesCount || (self._readableState.pipes && self._readableState.pipes.length)) self.push(entry); } @@ -171,7 +181,7 @@ class Parse extends PullStream { let eof; entry.__autodraining = __autodraining; // expose __autodraining for test purposes - const inflater = (vars.compressionMethod && !__autodraining) ? zlib.createInflateRaw() : Stream.PassThrough(); + const inflater = (vars.compressionMethod && !__autodraining) ? zlib.createInflateRaw() : new Stream.PassThrough(); if (fileSizeKnown) { entry.size = vars.uncompressedSize; diff --git a/lib/parseExtraField.js b/lib/parseExtraField.js index 42d178f..6f4b16a 100644 --- a/lib/parseExtraField.js +++ b/lib/parseExtraField.js @@ -1,7 +1,7 @@ const parseBuffer = require('./parseBuffer'); module.exports = function(extraField, vars) { - let extra; + let extra = {}; // Find the ZIP64 header, if present. while(!extra && extraField && extraField.length) { const candidateExtra = parseBuffer.parse(extraField, [ @@ -22,8 +22,6 @@ module.exports = function(extraField, vars) { } } - extra = extra || {}; - if (vars.compressedSize === 0xffffffff) vars.compressedSize = extra.compressedSize; diff --git a/lib/parseOne.js b/lib/parseOne.js index 275dde0..322220a 100644 --- a/lib/parseOne.js +++ b/lib/parseOne.js @@ -4,9 +4,9 @@ const duplexer2 = require('duplexer2'); const BufferStream = require('./BufferStream'); function parseOne(match, opts) { - const inStream = Stream.PassThrough({objectMode:true}); - const outStream = Stream.PassThrough(); - const transform = Stream.Transform({objectMode:true}); + const inStream = new Stream.PassThrough({objectMode:true}); + const outStream = new Stream.PassThrough(); + const transform = new Stream.Transform({objectMode:true}); const re = match instanceof RegExp ? match : (match && new RegExp(match)); let found; diff --git a/package.json b/package.json index 9f20cf8..82b944b 100644 --- a/package.json +++ b/package.json @@ -30,9 +30,10 @@ "graceful-fs": "^4.2.2" }, "devDependencies": { + "typescript": "^5.4.5", "@eslint/js": "^9.2.0", - "@types/node": "^20.12.11", "@types/bluebird": "^3.5.42", + "@types/node": "^20.12.11", "aws-sdk": "^2.77.0", "dirdiff": ">= 0.0.1 < 1", "eslint": "^9.2.0", diff --git a/test/compressed-crx.js b/test/compressed-crx.js index 865567e..2102717 100644 --- a/test/compressed-crx.js +++ b/test/compressed-crx.js @@ -42,17 +42,19 @@ test('open methods', async function(t) { const s3 = new AWS.S3({region: 'us-east-1'}); // We have to modify the `getObject` and `headObject` to use makeUnauthenticated + //@ts-ignore s3.getObject = function(params, cb) { return s3.makeUnauthenticatedRequest('getObject', params, cb); }; + //@ts-ignore s3.headObject = function(params, cb) { return s3.makeUnauthenticatedRequest('headObject', params, cb); }; const tests = [ - {name: 'buffer', args: [buffer]}, - {name: 'file', args: [archive]}, + {name: 'buffer', args: [buffer, {crx: true}]}, + {name: 'file', args: [archive, {crx: true}]}, // {name: 'url', args: [request, 'https://s3.amazonaws.com/unzipper/archive.crx']}, // {name: 's3', args: [s3, { Bucket: 'unzipper', Key: 'archive.crx'}]} ]; @@ -61,7 +63,7 @@ test('open methods', async function(t) { t.test(test.name, async function(t) { t.test('opening with crx option', function(t) { const method = unzip.Open[test.name]; - method.apply(method, test.args.concat({crx:true})) + method.apply(method, test.args) .then(function(d) { return d.files[1].buffer(); }) diff --git a/test/office-files.js b/test/office-files.js index b0a9fe4..719791e 100644 --- a/test/office-files.js +++ b/test/office-files.js @@ -19,14 +19,14 @@ test("get content a xlsx file without errors", async function () { test("stream retries when the local file header indicates bigger size than central directory", async function (t) { const archive = path.join(__dirname, '../testData/office/testfile.xlsx'); - let retries = 0, size; + let retries = 0, size = 0; const directory = await unzip.Open.file(archive, {padding: 10}); const stream = directory.files[0].stream(); stream.on('streamRetry', _size => { retries += 1; size = _size; }); - await new Promise(resolve => stream.pipe(NoopStream()).on('finish', resolve)); + await new Promise(resolve => stream.pipe(new NoopStream()).on('finish', resolve)); t.ok(retries === 1, 'retries once'); t.ok(size > 0, 'size is set'); }); \ No newline at end of file diff --git a/test/streamSingleEntry.js b/test/streamSingleEntry.js index 9fc4466..6a319c3 100644 --- a/test/streamSingleEntry.js +++ b/test/streamSingleEntry.js @@ -6,7 +6,7 @@ const unzip = require('../'); const Stream = require('stream'); test("pipe a single file entry out of a zip", function (t) { - const receiver = Stream.Transform({objectMode:true}); + const receiver = new Stream.Transform({objectMode:true}); receiver._transform = function(entry, e, cb) { if (entry.path === 'file.txt') { const writableStream = new streamBuffers.WritableStreamBuffer(); diff --git a/test/uncompressed.js b/test/uncompressed.js index 94af3fd..da113cc 100644 --- a/test/uncompressed.js +++ b/test/uncompressed.js @@ -63,7 +63,7 @@ test("do not extract zip slip archive", function (t) { fs.createReadStream(archive).pipe(unzipExtractor); function testNoSlip() { - const mode = fs.F_OK | (fs.constants && fs.constants.F_OK); + const mode = fs.constants.F_OK | (fs.constants && fs.constants.F_OK); return fs.access(path.join(os.tmpdir(), 'evil.txt'), mode, evilFileCallback); } @@ -105,7 +105,7 @@ function testZipSlipArchive(t, slipFileName, attackPathFactory){ function CheckForSlip(path, resultCallback) { const fsCallback = function(err){ return resultCallback(!err); }; - const mode = fs.F_OK | (fs.constants && fs.constants.F_OK); + const mode = fs.constants.F_OK | (fs.constants && fs.constants.F_OK); return fs.access(path, mode, fsCallback); }