Skip to content

Commit

Permalink
Merge pull request #318 from ZJONSSON/ayush-refactor
Browse files Browse the repository at this point in the history
#261 move away from unmaintained fstream (Ayush refactor)
  • Loading branch information
ZJONSSON authored Jun 8, 2024
2 parents 1149855 + 341aa44 commit 343956a
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 18 deletions.
16 changes: 11 additions & 5 deletions lib/Open/directory.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const unzip = require('./unzip');
const BufferStream = require('../BufferStream');
const parseExtraField = require('../parseExtraField');
const path = require('path');
const Writer = require('fstream').Writer;
const fs = require('fs-extra');
const parseDateTime = require('../parseDateTime');
const parseBuffer = require('../parseBuffer');
const Bluebird = require('bluebird');
Expand Down Expand Up @@ -153,17 +153,23 @@ module.exports = function centralDirectory(source, options) {
// make sure path is normalized before using it
opts.path = path.resolve(path.normalize(opts.path));
return vars.files.then(function(files) {
return Bluebird.map(files, function(entry) {
if (entry.type == 'Directory') return;

return Bluebird.map(files, async function(entry) {
// 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.
const extractPath = path.join(opts.path, entry.path);
if (extractPath.indexOf(opts.path) != 0) {
return;
}
const writer = opts.getWriter ? opts.getWriter({path: extractPath}) : Writer({ path: 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)
Expand Down
16 changes: 11 additions & 5 deletions lib/extract.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module.exports = Extract;

const Parse = require('./parse');
const Writer = require('fstream').Writer;
const fs = require('fs-extra');
const path = require('path');
const stream = require('stream');
const duplexer2 = require('duplexer2');
Expand All @@ -13,9 +13,7 @@ function Extract (opts) {
const parser = new Parse(opts);

const outStream = new stream.Writable({objectMode: true});
outStream._write = function(entry, encoding, cb) {

if (entry.type == 'Directory') return cb();
outStream._write = async function(entry, encoding, cb) {

// to avoid zip slip (writing outside of the destination), we resolve
// the target path, and make sure it's nested in the intended
Expand All @@ -27,7 +25,15 @@ function Extract (opts) {
return cb();
}

const writer = opts.getWriter ? opts.getWriter({path: extractPath}) : Writer({ path: 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)
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@
"big-integer": "^1.6.17",
"bluebird": "~3.4.1",
"duplexer2": "~0.1.4",
"fstream": "^1.0.12",
"fs-extra": "^11.2.0",
"graceful-fs": "^4.2.2"
},
"devDependencies": {
"@eslint/js": "^9.2.0",
"aws-sdk": "^2.77.0",
"aws-sdk": "^2.1636.0",
"dirdiff": ">= 0.0.1 < 1",
"eslint": "^9.2.0",
"globals": "^15.2.0",
Expand All @@ -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"
}
}
1 change: 0 additions & 1 deletion test/autodrain-passthrough.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ test("verify that autodrain promise works", function (t) {
});
})
.on('finish', function() {
console.log('end');
t.end();
});
});
Expand Down
2 changes: 1 addition & 1 deletion test/compressed-crx.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
11 changes: 9 additions & 2 deletions test/compressed.js
Original file line number Diff line number Diff line change
@@ -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');
Expand Down Expand Up @@ -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) {
Expand Down
10 changes: 9 additions & 1 deletion test/open-extract.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
42
11 changes: 11 additions & 0 deletions testData/compressed-standard-crx/inflated/file.txt
Original file line number Diff line number Diff line change
@@ -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.
Binary file modified testData/compressed-standard/archive.zip
Binary file not shown.

0 comments on commit 343956a

Please sign in to comment.