Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions lib/tar/file_stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,15 @@ class TarFileStream extends stream.Transform {

if (sourceType === 'file') {
// stat file to get file size
fs.stat(opts.source, (err, stat) => {
if (err) return this.emit('error', err);
fs.promises.stat(opts.source).then(stat => {
this.entry = pack.entry({ name: opts.relativePath || path.basename(opts.source), size: stat.size, mode: stat.mode & 0o777 }, err => {
if (err) return this.emit('error', err);
pack.finalize();
});
const stream = fs.createReadStream(opts.source, opts.fs);
stream.on('error', err => this.emit('error', err));
stream.pipe(this);
});
}).catch(err => this.emit('error', err));
} else if (sourceType === 'buffer') {
if (!opts.relativePath) return this.emit('error', 'opts.relativePath is required if opts.source is a buffer');

Expand Down
16 changes: 6 additions & 10 deletions lib/tar/stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,32 +45,28 @@ class TarStream extends BaseStream {
}

_addFileOrDirEntry(entry, opts) {
fs.stat(entry, (err, stat) => {
if (err) return this.emit('error', err);
fs.promises.stat(entry).then(stat => {
if (stat.isDirectory()) return this._addDirEntry(entry, opts);
if (stat.isFile()) return this._addFileEntry(entry, opts);

const illigalEntryError = new Error('Type is not supported, must be a file path, directory path, file buffer, or a readable stream');
illigalEntryError.name = 'IlligalEntryError';
this.emit('error', illigalEntryError);
});
}).catch(err => this.emit('error', err));
}

_addFileEntry(entry, opts) {
// stat file to get file size
fs.stat(entry, (err, stat) => {
if (err) return this.emit('error', err);
fs.promises.stat(entry).then(stat => {
const entryStream = this._pack.entry({ name: opts.relativePath || path.basename(entry), size: stat.size, mode: stat.mode & 0o777 }, this._onEntryFinish.bind(this));
const stream = fs.createReadStream(entry, opts.fs);
stream.on('error', err => this.emit('error', err));
stream.pipe(entryStream);
});
}).catch(err => this.emit('error', err));
}

_addDirEntry(entry, opts) {
fs.readdir(entry, (err, files) => {
if (err) return this.emit('error', err);

fs.promises.readdir(entry).then(files => {
const relativePath = opts.relativePath || '';
files.forEach(fileOrDir => {
const newOpts = utils.clone(opts);
Expand All @@ -83,7 +79,7 @@ class TarStream extends BaseStream {
this.addEntry(path.posix.join(entry, fileOrDir), newOpts);
});
this._onEntryFinish();
});
}).catch(err => this.emit('error', err));
}

_addBufferEntry(entry, opts) {
Expand Down
8 changes: 3 additions & 5 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ async function realpathWithMissingDirectories(dir) {
* Check if childPath is within parentPath (prevents path traversal attacks)
* @param {string} childPath - The path to check
* @param {string} parentPath - The parent directory path
* @returns {boolean} - True if childPath is within parentPath
* @return {boolean} - True if childPath is within parentPath
*/
function isPathWithinParent(childPath, parentPath) {
const normalizedChild = path.resolve(childPath);
Expand Down Expand Up @@ -225,9 +225,7 @@ exports.makeUncompressFn = StreamClass => {
delete opts.strip;

return new Promise((resolve, reject) => {
fs.mkdir(destDir, { recursive: true }, err => {
if (err) return reject(err);

fs.promises.mkdir(destDir, { recursive: true }).then(() => {
// Resolve destDir to absolute path for security validation
const resolvedDestDir = path.resolve(destDir);
// Resolve once for the entire extraction to handle OS-level symlinks
Expand Down Expand Up @@ -323,7 +321,7 @@ exports.makeUncompressFn = StreamClass => {
stream.on('end', next);
processEntry(header, stream).catch(reject);
});
});
}).catch(reject);
});
};
};
Expand Down
28 changes: 12 additions & 16 deletions test/tar/uncompress_stream.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,9 @@ describe('test/tar/uncompress_stream.test.js', () => {
.then(next)
.catch(done);
} else { // directory
fs.mkdir(path.join(destDir, header.name), { recursive: true }, err => {
if (err) return done(err);
stream.resume();
});
fs.promises.mkdir(path.join(destDir, header.name), { recursive: true })
.then(() => stream.resume())
.catch(done);
stream.on('end', next);
}
});
Expand All @@ -68,10 +67,9 @@ describe('test/tar/uncompress_stream.test.js', () => {
.then(next)
.catch(done);
} else { // directory
fs.mkdir(path.join(destDir, header.name), { recursive: true }, err => {
if (err) return done(err);
stream.resume();
});
fs.promises.mkdir(path.join(destDir, header.name), { recursive: true })
.then(() => stream.resume())
.catch(done);
stream.on('end', next);
}
});
Expand Down Expand Up @@ -102,10 +100,9 @@ describe('test/tar/uncompress_stream.test.js', () => {
.then(next)
.catch(done);
} else { // directory
fs.mkdir(path.join(destDir, header.name), err => {
if (err) return done(err);
stream.resume();
});
fs.promises.mkdir(path.join(destDir, header.name))
.then(() => stream.resume())
.catch(done);
stream.on('end', next);
}
});
Expand Down Expand Up @@ -133,10 +130,9 @@ describe('test/tar/uncompress_stream.test.js', () => {
.then(next)
.catch(done);
} else { // directory
fs.mkdir(path.join(destDir, header.name), { recursive: true }, err => {
if (err) return done(err);
stream.resume();
});
fs.promises.mkdir(path.join(destDir, header.name), { recursive: true })
.then(() => stream.resume())
.catch(done);
stream.on('end', next);
}
});
Expand Down
28 changes: 12 additions & 16 deletions test/tgz/uncompress_stream.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,9 @@ describe('test/tgz/uncompress_stream.test.js', () => {
.then(next)
.catch(done);
} else { // directory
fs.mkdir(path.join(destDir, header.name), { recursive: true }, err => {
if (err) return done(err);
stream.resume();
});
fs.promises.mkdir(path.join(destDir, header.name), { recursive: true })
.then(() => stream.resume())
.catch(done);
stream.on('end', next);
}
});
Expand Down Expand Up @@ -69,10 +68,9 @@ describe('test/tgz/uncompress_stream.test.js', () => {
.then(next)
.catch(done);
} else { // directory
fs.mkdir(path.join(destDir, header.name), { recursive: true }, err => {
if (err) return done(err);
stream.resume();
});
fs.promises.mkdir(path.join(destDir, header.name), { recursive: true })
.then(() => stream.resume())
.catch(done);
stream.on('end', next);
}
});
Expand Down Expand Up @@ -100,10 +98,9 @@ describe('test/tgz/uncompress_stream.test.js', () => {
.then(next)
.catch(done);
} else { // directory
fs.mkdir(path.join(destDir, header.name), { recursive: true }, err => {
if (err) return done(err);
stream.resume();
});
fs.promises.mkdir(path.join(destDir, header.name), { recursive: true })
.then(() => stream.resume())
.catch(done);
stream.on('end', next);
}
});
Expand Down Expand Up @@ -134,10 +131,9 @@ describe('test/tgz/uncompress_stream.test.js', () => {
.then(next)
.catch(done);
} else { // directory
fs.mkdir(path.join(destDir, header.name), { recursive: true }, err => {
if (err) return done(err);
stream.resume();
});
fs.promises.mkdir(path.join(destDir, header.name), { recursive: true })
.then(() => stream.resume())
.catch(done);
stream.on('end', next);
}
});
Expand Down
42 changes: 18 additions & 24 deletions test/zip/uncompress_stream.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,9 @@ describe('test/zip/uncompress_stream.test.js', () => {
.then(next)
.catch(done);
} else { // directory
fs.mkdir(path.join(destDir, header.name), { recursive: true }, err => {
if (err) return done(err);
stream.resume();
});
fs.promises.mkdir(path.join(destDir, header.name), { recursive: true })
.then(() => stream.resume())
.catch(done);
stream.on('end', next);
}
});
Expand Down Expand Up @@ -78,10 +77,9 @@ describe('test/zip/uncompress_stream.test.js', () => {
.then(next)
.catch(done);
} else { // directory
fs.mkdir(path.join(destDir, header.name), { recursive: true }, err => {
if (err) return done(err);
stream.resume();
});
fs.promises.mkdir(path.join(destDir, header.name), { recursive: true })
.then(() => stream.resume())
.catch(done);
stream.on('end', next);
}
});
Expand Down Expand Up @@ -111,10 +109,9 @@ describe('test/zip/uncompress_stream.test.js', () => {
.then(next)
.catch(done);
} else { // directory
fs.mkdir(path.join(destDir, header.name), { recursive: true }, err => {
if (err) return done(err);
stream.resume();
});
fs.promises.mkdir(path.join(destDir, header.name), { recursive: true })
.then(() => stream.resume())
.catch(done);
stream.on('end', next);
}
});
Expand Down Expand Up @@ -144,10 +141,9 @@ describe('test/zip/uncompress_stream.test.js', () => {
.then(next)
.catch(done);
} else { // directory
fs.mkdir(path.join(destDir, header.name), { recursive: true }, err => {
if (err) return done(err);
stream.resume();
});
fs.promises.mkdir(path.join(destDir, header.name), { recursive: true })
.then(() => stream.resume())
.catch(done);
stream.on('end', next);
}
});
Expand Down Expand Up @@ -206,10 +202,9 @@ describe('test/zip/uncompress_stream.test.js', () => {
.then(next)
.catch(done);
} else { // directory
fs.mkdir(path.join(destDir, header.name), { recursive: true }, err => {
if (err) return done(err);
stream.resume();
});
fs.promises.mkdir(path.join(destDir, header.name), { recursive: true })
.then(() => stream.resume())
.catch(done);
stream.on('end', next);
}
});
Expand Down Expand Up @@ -237,10 +232,9 @@ describe('test/zip/uncompress_stream.test.js', () => {
.then(next)
.catch(done);
} else { // directory
fs.mkdir(path.join(destDir, header.name), { recursive: true }, err => {
if (err) return done(err);
stream.resume();
});
fs.promises.mkdir(path.join(destDir, header.name), { recursive: true })
.then(() => stream.resume())
.catch(done);
stream.on('end', next);
}
});
Expand Down
Loading