From 23b49dc82cef2a1df1cfe5c6b1eb64ff5e7639f6 Mon Sep 17 00:00:00 2001 From: jrainliu Date: Thu, 1 Feb 2024 14:11:56 +0800 Subject: [PATCH] fix: fix symlink pointing error in filesystem.insertLink --- lib/filesystem.js | 4 +++- test/api-spec.js | 5 +++++ test/input/packthis-with-symlink/A/real.txt | 1 + test/input/packthis-with-symlink/Current | 1 + test/input/packthis-with-symlink/real.txt | 1 + test/util/compareFiles.js | 17 +++++++++++++++-- 6 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 test/input/packthis-with-symlink/A/real.txt create mode 120000 test/input/packthis-with-symlink/Current create mode 120000 test/input/packthis-with-symlink/real.txt diff --git a/lib/filesystem.js b/lib/filesystem.js index f61c0410..27b00a1b 100644 --- a/lib/filesystem.js +++ b/lib/filesystem.js @@ -99,7 +99,9 @@ class Filesystem { } insertLink (p) { - const link = path.relative(fs.realpathSync(this.src), fs.realpathSync(p)) + const symlink = fs.readlinkSync(p) + const parentPath = path.dirname(p) + const link = path.relative(fs.realpathSync(this.src), path.join(parentPath, symlink)) if (link.substr(0, 2) === '..') { throw new Error(`${p}: file "${link}" links out of the package`) } diff --git a/test/api-spec.js b/test/api-spec.js index d50323d1..2239d1ac 100644 --- a/test/api-spec.js +++ b/test/api-spec.js @@ -81,6 +81,11 @@ describe('api', function () { asar.extractAll('test/input/extractthis-unpack-dir.asar', 'tmp/extractthis-unpack-dir-api/') return compDirs('tmp/extractthis-unpack-dir-api/', 'test/expected/extractthis') }) + it('should extract an archive with symlink', async () => { + await asar.createPackageWithOptions('test/input/packthis-with-symlink/', 'tmp/packthis-with-symlink.asar', { dot: false }) + asar.extractAll('tmp/packthis-with-symlink.asar', 'tmp/packthis-with-symlink/') + return compFiles('tmp/packthis-with-symlink/real.txt', 'test/input/packthis-with-symlink/real.txt') + }) it('should handle multibyte characters in paths', async () => { await asar.createPackageWithOptions('test/input/packthis-unicode-path/', 'tmp/packthis-unicode-path.asar', { globOptions: { diff --git a/test/input/packthis-with-symlink/A/real.txt b/test/input/packthis-with-symlink/A/real.txt new file mode 100644 index 00000000..59f6076f --- /dev/null +++ b/test/input/packthis-with-symlink/A/real.txt @@ -0,0 +1 @@ +I AM REAL TXT FILE diff --git a/test/input/packthis-with-symlink/Current b/test/input/packthis-with-symlink/Current new file mode 120000 index 00000000..8c7e5a66 --- /dev/null +++ b/test/input/packthis-with-symlink/Current @@ -0,0 +1 @@ +A \ No newline at end of file diff --git a/test/input/packthis-with-symlink/real.txt b/test/input/packthis-with-symlink/real.txt new file mode 120000 index 00000000..abbcc031 --- /dev/null +++ b/test/input/packthis-with-symlink/real.txt @@ -0,0 +1 @@ +Current/real.txt \ No newline at end of file diff --git a/test/util/compareFiles.js b/test/util/compareFiles.js index 485ba2bf..d80d9aae 100644 --- a/test/util/compareFiles.js +++ b/test/util/compareFiles.js @@ -7,6 +7,19 @@ module.exports = async function (actualFilePath, expectedFilePath) { if (process.env.ELECTRON_ASAR_SPEC_UPDATE) { await fs.writeFile(expectedFilePath, await fs.readFile(actualFilePath)) } - const [actual, expected] = await Promise.all([fs.readFile(actualFilePath, 'utf8'), fs.readFile(expectedFilePath, 'utf8')]) - assert.strictEqual(actual, expected) + const [actualFileContent, expectedFileContent] = await Promise.all([fs.readFile(actualFilePath, 'utf8'), fs.readFile(expectedFilePath, 'utf8')]) + assert.strictEqual(actualFileContent, expectedFileContent) + + const [actualIsSymlink, expectedIsSymlink] = [isSymbolicLinkSync(actualFilePath), isSymbolicLinkSync(expectedFilePath)] + assert.strictEqual(actualIsSymlink, expectedIsSymlink) + + if (actualIsSymlink && expectedIsSymlink) { + const [actualSymlinkPointer, expectedSymlinkPointer] = [fs.readlinkSync(actualFilePath), fs.readlinkSync(expectedFilePath)] + assert.strictEqual(actualSymlinkPointer, expectedSymlinkPointer) + } +} + +function isSymbolicLinkSync (path) { + const stats = fs.lstatSync(path) + return stats.isSymbolicLink() }