Skip to content

Commit

Permalink
Attempt to resolve another escape case
Browse files Browse the repository at this point in the history
  • Loading branch information
trptcolin committed Feb 28, 2020
1 parent 2d797ce commit 795aa69
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 9 deletions.
Binary file added fixtures/slip2.zip
Binary file not shown.
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const extractFile = (input, output, opts) => runPlugins(input, opts).then(files
.then(() => {
return Promise.all([fsP.realpath(path.dirname(dest)), fsP.realpath(output)])
.then(([realDestinationDir, realOutputDir]) => {
if (realDestinationDir.indexOf(realOutputDir) !== 0) {
if (dest.indexOf(realOutputDir) !== 0 || realDestinationDir.indexOf(realOutputDir) !== 0) {
throw (new Error('Refusing to write outside output directory: ' + realDestinationDir));
}
});
Expand Down
22 changes: 14 additions & 8 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import m from '.';
const fsP = pify(fs);
const rimrafP = pify(rimraf);

test.after('ensure decompressed files and directories are cleaned up', async () => {
test.serial.afterEach('ensure decompressed files and directories are cleaned up', async () => {
await rimrafP(path.join(__dirname, 'directory'));
await rimrafP(path.join(__dirname, 'dist'));
await rimrafP(path.join(__dirname, 'file.txt'));
await rimrafP(path.join(__dirname, 'edge_case_dots'));
await rimrafP(path.join(__dirname, 'symlink'));
await rimrafP(path.join(__dirname, 'test.jpg'));
});

Expand Down Expand Up @@ -57,14 +59,12 @@ test.serial('extract file to directory', async t => {
t.true(await pathExists(path.join(__dirname, 'test.jpg')));
});

test('extract symlink', async t => {
test.serial('extract symlink', async t => {
await m(path.join(__dirname, 'fixtures', 'symlink.tar'), __dirname, {strip: 1});
t.is(await fsP.realpath(path.join(__dirname, 'symlink')), path.join(__dirname, 'file.txt'));
await fsP.unlink(path.join(__dirname, 'symlink'));
await fsP.unlink(path.join(__dirname, 'file.txt'));
});

test('extract directory', async t => {
test.serial('extract directory', async t => {
await m(path.join(__dirname, 'fixtures', 'directory.tar'), __dirname);
t.true(await pathExists(path.join(__dirname, 'directory')));
});
Expand Down Expand Up @@ -115,19 +115,25 @@ test('throw when a location outside the root is given', async t => {
}, {message: /Refusing/});
});

test('throw when a location outside the root including symlinks is given', async t => {
test.serial('throw when a location outside the root including symlinks is given', async t => {
await t.throwsAsync(async () => {
await m(path.join(__dirname, 'fixtures', 'slip.zip'), 'dist');
}, {message: /Refusing/});
});

test('throw when a directory outside the root including symlinks is given', async t => {
test.serial('throw when a top-level symlink outside the root is given', async t => {
await t.throwsAsync(async () => {
await m(path.join(__dirname, 'fixtures', 'slip2.zip'), 'dist');
}, {message: /Refusing/});
});

test.serial('throw when a directory outside the root including symlinks is given', async t => {
await t.throwsAsync(async () => {
await m(path.join(__dirname, 'fixtures', 'slipping_directory.tar.gz'), 'dist');
}, {message: /Refusing/});
});

test('allows filenames and directories to be written with dots in their names', async t => {
test.serial('allows filenames and directories to be written with dots in their names', async t => {
const files = await m(path.join(__dirname, 'fixtures', 'edge_case_dots.tar.gz'), __dirname);
t.is(files.length, 6);
t.deepEqual(files.map(f => f.path).sort(), [
Expand Down

1 comment on commit 795aa69

@trptcolin
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also adds some serial bits to the tests that write files to the filesystem - this prevented some failures due to concurrent execution.

Please sign in to comment.