From 21f3e9beb150601c605f7c5e440d67b5b7103c88 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 94ae8ec9..17ff5a7c 100644 --- a/lib/unpack.js +++ b/lib/unpack.js @@ -219,6 +219,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 1e39b654..348e20ad 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() }