Skip to content

Commit 9dbdeb6

Browse files
committedJul 26, 2021
Remove paths from dirCache when no longer dirs
1 parent 1e33534 commit 9dbdeb6

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed
 

‎lib/unpack.js

+22
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,19 @@ class Unpack extends Parser {
465465
}
466466

467467
[CHECKFS2] (entry, done) {
468+
// if we are not creating a directory, and the path is in the dirCache,
469+
// then that means we are about to delete the directory we created
470+
// previously, and it is no longer going to be a directory, and neither
471+
// is any of its children.
472+
if (entry.type !== 'Directory') {
473+
for (const path of this.dirCache.keys()) {
474+
if (path === entry.absolute ||
475+
path.indexOf(entry.absolute + '/') === 0 ||
476+
path.indexOf(entry.absolute + '\\') === 0)
477+
this.dirCache.delete(path)
478+
}
479+
}
480+
468481
this[MKDIR](path.dirname(entry.absolute), this.dmode, er => {
469482
if (er) {
470483
done()
@@ -529,6 +542,15 @@ class Unpack extends Parser {
529542

530543
class UnpackSync extends Unpack {
531544
[CHECKFS] (entry) {
545+
if (entry.type !== 'Directory') {
546+
for (const path of this.dirCache.keys()) {
547+
if (path === entry.absolute ||
548+
path.indexOf(entry.absolute + '/') === 0 ||
549+
path.indexOf(entry.absolute + '\\') === 0)
550+
this.dirCache.delete(path)
551+
}
552+
}
553+
532554
const er = this[MKDIR](path.dirname(entry.absolute), this.dmode, neverCalled)
533555
if (er)
534556
return this[ONERROR](er, entry)

‎test/unpack.js

+53
Original file line numberDiff line numberDiff line change
@@ -2605,3 +2605,56 @@ t.test('handle errors on fs.close', t => {
26052605
cwd: dir + '/sync', strict: true,
26062606
}).end(data), poop, 'sync')
26072607
})
2608+
2609+
t.test('drop entry from dirCache if no longer a directory', t => {
2610+
const dir = path.resolve(unpackdir, 'dir-cache-error')
2611+
mkdirp.sync(dir + '/sync/y')
2612+
mkdirp.sync(dir + '/async/y')
2613+
const data = makeTar([
2614+
{
2615+
path: 'x',
2616+
type: 'Directory',
2617+
},
2618+
{
2619+
path: 'x',
2620+
type: 'SymbolicLink',
2621+
linkpath: './y',
2622+
},
2623+
{
2624+
path: 'x/ginkoid',
2625+
type: 'File',
2626+
size: 'ginkoid'.length,
2627+
},
2628+
'ginkoid',
2629+
'',
2630+
'',
2631+
])
2632+
t.plan(2)
2633+
const WARNINGS = {}
2634+
const check = (t, path) => {
2635+
t.equal(fs.statSync(path + '/x').isDirectory(), true)
2636+
t.equal(fs.lstatSync(path + '/x').isSymbolicLink(), true)
2637+
t.equal(fs.statSync(path + '/y').isDirectory(), true)
2638+
t.strictSame(fs.readdirSync(path + '/y'), [])
2639+
t.throws(() => fs.readFileSync(path + '/x/ginkoid'), { code: 'ENOENT' })
2640+
t.strictSame(WARNINGS[path], [
2641+
'TAR_ENTRY_ERROR',
2642+
'Cannot extract through symbolic link',
2643+
])
2644+
t.end()
2645+
}
2646+
t.test('async', t => {
2647+
const path = dir + '/async'
2648+
new Unpack({ cwd: path })
2649+
.on('warn', (code, msg) => WARNINGS[path] = [code, msg])
2650+
.on('end', () => check(t, path))
2651+
.end(data)
2652+
})
2653+
t.test('sync', t => {
2654+
const path = dir + '/sync'
2655+
new UnpackSync({ cwd: path })
2656+
.on('warn', (code, msg) => WARNINGS[path] = [code, msg])
2657+
.end(data)
2658+
check(t, path)
2659+
})
2660+
})

1 commit comments

Comments
 (1)

RonSherfey commented on Aug 17, 2021

@RonSherfey

changes to NPM vulnerabilities

Please sign in to comment.