From 6aafff0a8621ba9509b63654bde28762be373d58 Mon Sep 17 00:00:00 2001 From: isaacs Date: Tue, 10 Aug 2021 15:30:46 -0700 Subject: [PATCH] fix: skip extract if linkpath is stripped entirely Fix tar.Unpack() to skip extraction of hardlinks and symlinks when a 'strip' option is provided, if the entry linkpath would be completely stripped. Previously, the linkpath would not be stripped if it had fewer path parts than the strip option. This matches the behavior of modern versions of bsdtar. Gnutar has the same extraction semantics, but emits a warning when the resulting linkpath is completely stripped. --- lib/unpack.js | 2 ++ test/unpack.js | 12 ++---------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/lib/unpack.js b/lib/unpack.js index a027ca02..29472a2a 100644 --- a/lib/unpack.js +++ b/lib/unpack.js @@ -209,6 +209,8 @@ class Unpack extends Parser { const linkparts = normPath(entry.linkpath).split('/') if (linkparts.length >= this.strip) entry.linkpath = linkparts.slice(this.strip).join('/') + else + return false } } diff --git a/test/unpack.js b/test/unpack.js index 2c18ccc9..9874271b 100644 --- a/test/unpack.js +++ b/test/unpack.js @@ -191,16 +191,8 @@ t.test('links!', t => { t.end() } const checkForStrip3 = t => { - t.ok(fs.lstatSync(dir + '/3').isDirectory()) - let err = null - try { - fs.lstatSync(dir + '/3/hardlink-3') - } catch(e) { - err = e - } - // can't be extracted because we've passed it in the tar - // (specially crafted tar for this not to work) - t.equal(err.code, 'ENOENT') + // strips the linkpath entirely, so the link doesn't get extracted. + t.throws(() => fs.lstatSync(dir + '/3'), { code: 'ENOENT' }) t.end() }