From 341aa44e0ac008206bbfe3c0236d1b7d913bbe9a Mon Sep 17 00:00:00 2001 From: Ziggy Jonsson Date: Sat, 8 Jun 2024 12:09:04 -0400 Subject: [PATCH] Make empty directories --- lib/Open/directory.js | 16 +++++++--------- lib/extract.js | 15 +++++++-------- package.json | 2 +- test/autodrain-passthrough.js | 1 - test/compressed-crx.js | 2 +- test/compressed.js | 11 +++++++++-- test/open-extract.js | 10 +++++++++- .../inflated/dir/fileInsideDir.txt | 1 + .../compressed-standard-crx/inflated/file.txt | 11 +++++++++++ testData/compressed-standard/archive.zip | Bin 1636 -> 2096 bytes 10 files changed, 46 insertions(+), 23 deletions(-) create mode 100644 testData/compressed-standard-crx/inflated/dir/fileInsideDir.txt create mode 100644 testData/compressed-standard-crx/inflated/file.txt diff --git a/lib/Open/directory.js b/lib/Open/directory.js index 8dd3f41..20b9e5f 100644 --- a/lib/Open/directory.js +++ b/lib/Open/directory.js @@ -154,8 +154,6 @@ module.exports = function centralDirectory(source, options) { opts.path = path.resolve(path.normalize(opts.path)); return vars.files.then(function(files) { return Bluebird.map(files, async function(entry) { - if (entry.type == 'Directory') return; - // to avoid zip slip (writing outside of the destination), we resolve // the target path, and make sure it's nested in the intended // destination, or not extract it otherwise. @@ -164,15 +162,15 @@ module.exports = function centralDirectory(source, options) { return; } - let writer; - - if (opts.getWriter) { - writer = opts.getWriter({path: extractPath}); - } else { - await fs.ensureDir(path.dirname(extractPath)); - writer = fs.createWriteStream(extractPath); + if (entry.type == 'Directory') { + await fs.ensureDir(extractPath); + return; } + await fs.ensureDir(path.dirname(extractPath)); + + const writer = opts.getWriter ? opts.getWriter({path: extractPath}) : fs.createWriteStream(extractPath); + return new Promise(function(resolve, reject) { entry.stream(opts.password) .on('error', reject) diff --git a/lib/extract.js b/lib/extract.js index 214635c..2991c54 100644 --- a/lib/extract.js +++ b/lib/extract.js @@ -15,8 +15,6 @@ function Extract (opts) { const outStream = new stream.Writable({objectMode: true}); outStream._write = async function(entry, encoding, cb) { - if (entry.type == 'Directory') return cb(); - // to avoid zip slip (writing outside of the destination), we resolve // the target path, and make sure it's nested in the intended // destination, or not extract it otherwise. @@ -27,15 +25,16 @@ function Extract (opts) { return cb(); } - let writer; - if (opts.getWriter) { - writer = opts.getWriter({path: extractPath}); - } else { - await fs.ensureDir(path.dirname(extractPath)); - writer = fs.createWriteStream(extractPath); + if (entry.type == 'Directory') { + await fs.ensureDir(extractPath); + return cb(); } + await fs.ensureDir(path.dirname(extractPath)); + + const writer = opts.getWriter ? opts.getWriter({path: extractPath}) : fs.createWriteStream(extractPath); + entry.pipe(writer) .on('error', cb) .on('close', cb); diff --git a/package.json b/package.json index 86712dc..cb2b905 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,6 @@ ], "main": "unzip.js", "scripts": { - "test": "npx tap test/*.js --coverage-report=html" + "test": "npx tap test/*.js --coverage-report=html --reporter=dot" } } diff --git a/test/autodrain-passthrough.js b/test/autodrain-passthrough.js index 968efdc..9e28775 100644 --- a/test/autodrain-passthrough.js +++ b/test/autodrain-passthrough.js @@ -32,7 +32,6 @@ test("verify that autodrain promise works", function (t) { }); }) .on('finish', function() { - console.log('end'); t.end(); }); }); diff --git a/test/compressed-crx.js b/test/compressed-crx.js index 865567e..39e3044 100644 --- a/test/compressed-crx.js +++ b/test/compressed-crx.js @@ -22,7 +22,7 @@ test('parse/extract crx archive', function (t) { function testExtractionResults() { t.same(unzipExtractor.crxHeader.version, 2); - dirdiff(path.join(__dirname, '../testData/compressed-standard/inflated'), dirPath, { + dirdiff(path.join(__dirname, '../testData/compressed-standard-crx/inflated'), dirPath, { fileContents: true }, function (err, diffs) { if (err) { diff --git a/test/compressed.js b/test/compressed.js index e154cab..1204fb1 100644 --- a/test/compressed.js +++ b/test/compressed.js @@ -1,5 +1,5 @@ const test = require('tap').test; -const fs = require('fs'); +const fs = require('fs-extra'); const path = require('path'); const temp = require('temp'); const dirdiff = require('dirdiff'); @@ -49,7 +49,14 @@ test("extract compressed archive w/ file sizes known prior to zlib inflation (cr fs.createReadStream(archive).pipe(unzipExtractor); - function testExtractionResults() { + async function testExtractionResults() { + const root = path.resolve(__dirname, '../testData/compressed-standard/inflated'); + + // since empty directories can not be checked into git we have to + // create them + await fs.ensureDir(path.resolve(root, 'emptydir')); + await fs.ensureDir(path.resolve(root, 'emptyroot/emptydir')); + dirdiff(path.join(__dirname, '../testData/compressed-standard/inflated'), dirPath, { fileContents: true }, function (err, diffs) { diff --git a/test/open-extract.js b/test/open-extract.js index f14347e..a184338 100644 --- a/test/open-extract.js +++ b/test/open-extract.js @@ -3,6 +3,7 @@ const path = require('path'); const temp = require('temp'); const dirdiff = require('dirdiff'); const unzip = require('../'); +const fs = require('fs-extra'); test("extract compressed archive with open.file.extract", function (t) { @@ -16,7 +17,14 @@ test("extract compressed archive with open.file.extract", function (t) { .then(function(d) { return d.extract({path: dirPath}); }) - .then(function() { + .then(async function() { + const root = path.resolve(__dirname, '../testData/compressed-standard/inflated'); + + // since empty directories can not be checked into git we have to + // create them + await fs.ensureDir(path.resolve(root, 'emptydir')); + await fs.ensureDir(path.resolve(root, 'emptyroot/emptydir')); + dirdiff(path.join(__dirname, '../testData/compressed-standard/inflated'), dirPath, { fileContents: true }, function (err, diffs) { diff --git a/testData/compressed-standard-crx/inflated/dir/fileInsideDir.txt b/testData/compressed-standard-crx/inflated/dir/fileInsideDir.txt new file mode 100644 index 0000000..d81cc07 --- /dev/null +++ b/testData/compressed-standard-crx/inflated/dir/fileInsideDir.txt @@ -0,0 +1 @@ +42 diff --git a/testData/compressed-standard-crx/inflated/file.txt b/testData/compressed-standard-crx/inflated/file.txt new file mode 100644 index 0000000..ac65224 --- /dev/null +++ b/testData/compressed-standard-crx/inflated/file.txt @@ -0,0 +1,11 @@ +node.js rocks + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras commodo molestie nunc, eu pharetra libero accumsan nec. Vestibulum hendrerit, augue ac congue varius, enim metus congue quam, imperdiet gravida diam felis nec dui. Morbi ipsum enim, tristique nec congue a, commodo ac sapien. Praesent semper metus quis diam hendrerit ut condimentum eros lobortis. Aenean faucibus arcu nec leo aliquam tincidunt. Nunc bibendum dictum bibendum. Nunc ultricies pretium lacus, sit amet lobortis quam egestas quis. Fusce viverra magna rhoncus sem posuere non tempus nulla vestibulum. + +Sed aliquet, odio vel condimentum pellentesque, mauris risus iaculis elit, at congue erat mi at ante. In at dictum metus. Ut rutrum mauris felis. Nulla sed risus nunc, eget ultrices est. Nullam gravida diam in arcu vulputate varius. Sed id egestas magna. Ut a libero sapien. + +Integer congue felis ut nisl fringilla ac interdum est pretium. Proin tellus augue, molestie id ultricies placerat, ornare a felis. In eu nibh velit. Pellentesque cursus ultricies fermentum. Mauris eget velit tempor nulla bibendum accumsan sit amet a ante. Morbi rutrum tempor varius. Aenean congue leo vitae mi suscipit ac tempor nibh pulvinar. Maecenas risus eros, sodales quis tincidunt non, vulputate eget orci. Maecenas condimentum lectus pretium orci adipiscing interdum. Sed interdum vehicula urna ut scelerisque. + +Phasellus pellentesque tellus in neque auctor pellentesque adipiscing justo consequat. In tincidunt rhoncus mollis. Suspendisse quis est elit, vel semper lorem. Donec cursus, leo ac fermentum luctus, dui dolor pretium nunc, vel congue eros arcu sit amet enim. Nam nibh orci, laoreet id volutpat eu, aliquet sed ligula. Donec placerat sagittis leo, eget hendrerit nisi varius sed. In pharetra erat non justo interdum id tempus purus tempor. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse felis leo, pellentesque tristique iaculis consequat, vestibulum a erat. Curabitur ligula risus, consectetur at adipiscing sit amet, accumsan non justo. Proin ultricies molestie lorem et auctor. Duis commodo varius semper. Ut tempus porttitor dolor nec mattis. Cras massa eros, tincidunt eget placerat a, luctus eu arcu. Nulla ac orci vitae odio dapibus dictum vitae porta erat. + +Duis luctus convallis euismod. Integer orci massa, bibendum eu blandit quis, facilisis lobortis purus. Donec et sapien quis elit fermentum cursus a ut lacus. Nullam tellus felis, congue et pulvinar sit amet, luctus ac augue. Sed massa nunc, dignissim non viverra ac, dictum sit amet erat. Sed nunc tortor, convallis et tristique ut, aliquam ut orci. Integer nec magna vitae elit sagittis accumsan id ac mi. diff --git a/testData/compressed-standard/archive.zip b/testData/compressed-standard/archive.zip index 327aab671637f9166c02409b11cb4298f09960e6..961bad256ed5a679b34eb9df6376b604192bab0c 100644 GIT binary patch delta 494 zcmaFDvq4}(ENeY83l{?jh{c_V05hNjCxZ+_YHmSEWlCm|erO0M19Nn3N*V~4R&X;g zvb&?wn3WCWJ3clBHip-X3=H~UE&xL6UhDt> delta 32 hcmdlW@PubWEbC-Lw$CE0Yz#oa41}M7bTli72LOnb1^55}