Skip to content

Commit

Permalink
Remove paths from dirCache when no longer dirs
Browse files Browse the repository at this point in the history
  • Loading branch information
isaacs committed Jul 26, 2021
1 parent 1e33534 commit 9dbdeb6
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 0 deletions.
22 changes: 22 additions & 0 deletions lib/unpack.js
Expand Up @@ -465,6 +465,19 @@ class Unpack extends Parser {
}

[CHECKFS2] (entry, done) {
// if we are not creating a directory, and the path is in the dirCache,
// then that means we are about to delete the directory we created
// previously, and it is no longer going to be a directory, and neither
// is any of its children.
if (entry.type !== 'Directory') {
for (const path of this.dirCache.keys()) {
if (path === entry.absolute ||
path.indexOf(entry.absolute + '/') === 0 ||
path.indexOf(entry.absolute + '\\') === 0)
this.dirCache.delete(path)
}
}

this[MKDIR](path.dirname(entry.absolute), this.dmode, er => {
if (er) {
done()
Expand Down Expand Up @@ -529,6 +542,15 @@ class Unpack extends Parser {

class UnpackSync extends Unpack {
[CHECKFS] (entry) {
if (entry.type !== 'Directory') {
for (const path of this.dirCache.keys()) {
if (path === entry.absolute ||
path.indexOf(entry.absolute + '/') === 0 ||
path.indexOf(entry.absolute + '\\') === 0)
this.dirCache.delete(path)
}
}

const er = this[MKDIR](path.dirname(entry.absolute), this.dmode, neverCalled)
if (er)
return this[ONERROR](er, entry)
Expand Down
53 changes: 53 additions & 0 deletions test/unpack.js
Expand Up @@ -2605,3 +2605,56 @@ t.test('handle errors on fs.close', t => {
cwd: dir + '/sync', strict: true,
}).end(data), poop, 'sync')
})

t.test('drop entry from dirCache if no longer a directory', t => {
const dir = path.resolve(unpackdir, 'dir-cache-error')
mkdirp.sync(dir + '/sync/y')
mkdirp.sync(dir + '/async/y')
const data = makeTar([
{
path: 'x',
type: 'Directory',
},
{
path: 'x',
type: 'SymbolicLink',
linkpath: './y',
},
{
path: 'x/ginkoid',
type: 'File',
size: 'ginkoid'.length,
},
'ginkoid',
'',
'',
])
t.plan(2)
const WARNINGS = {}
const check = (t, path) => {
t.equal(fs.statSync(path + '/x').isDirectory(), true)
t.equal(fs.lstatSync(path + '/x').isSymbolicLink(), true)
t.equal(fs.statSync(path + '/y').isDirectory(), true)
t.strictSame(fs.readdirSync(path + '/y'), [])
t.throws(() => fs.readFileSync(path + '/x/ginkoid'), { code: 'ENOENT' })
t.strictSame(WARNINGS[path], [
'TAR_ENTRY_ERROR',
'Cannot extract through symbolic link',
])
t.end()
}
t.test('async', t => {
const path = dir + '/async'
new Unpack({ cwd: path })
.on('warn', (code, msg) => WARNINGS[path] = [code, msg])
.on('end', () => check(t, path))
.end(data)
})
t.test('sync', t => {
const path = dir + '/sync'
new UnpackSync({ cwd: path })
.on('warn', (code, msg) => WARNINGS[path] = [code, msg])
.end(data)
check(t, path)
})
})

1 comment on commit 9dbdeb6

@RonSherfey
Copy link

Choose a reason for hiding this comment

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

changes to NPM vulnerabilities

Please sign in to comment.