From 9b02d94e9767d67a7b176bffc009e70fe5767b7a Mon Sep 17 00:00:00 2001 From: Avi Vahl Date: Tue, 15 Dec 2020 04:21:49 +0200 Subject: [PATCH] fix(asar): readdir(withFileTypes) fails on deep directory (#26865) when using readdirSync on a deep directory within the archive, the code fails to get the stats of child paths. --- lib/asar/fs-wrapper.ts | 10 ++++++---- spec/asar-spec.js | 10 ++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/lib/asar/fs-wrapper.ts b/lib/asar/fs-wrapper.ts index f48953dbaf2a..f6827fda3a14 100644 --- a/lib/asar/fs-wrapper.ts +++ b/lib/asar/fs-wrapper.ts @@ -615,9 +615,10 @@ export const wrapFsWithAsar = (fs: Record) => { if (options.withFileTypes) { const dirents = []; for (const file of files) { - const stats = archive.stat(file); + const childPath = path.join(filePath, file); + const stats = archive.stat(childPath); if (!stats) { - const error = createError(AsarError.NOT_FOUND, { asarPath, filePath: file }); + const error = createError(AsarError.NOT_FOUND, { asarPath, filePath: childPath }); nextTick(callback!, [error]); return; } @@ -657,9 +658,10 @@ export const wrapFsWithAsar = (fs: Record) => { if (options && (options as any).withFileTypes) { const dirents = []; for (const file of files) { - const stats = archive.stat(file); + const childPath = path.join(filePath, file); + const stats = archive.stat(childPath); if (!stats) { - throw createError(AsarError.NOT_FOUND, { asarPath, filePath: file }); + throw createError(AsarError.NOT_FOUND, { asarPath, filePath: childPath }); } if (stats.isFile) { dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_FILE)); diff --git a/spec/asar-spec.js b/spec/asar-spec.js index 9e17081a8430..be78c7e70a47 100644 --- a/spec/asar-spec.js +++ b/spec/asar-spec.js @@ -920,6 +920,16 @@ describe('asar package', function () { expect(names).to.deep.equal(['dir1', 'dir2', 'dir3', 'file1', 'file2', 'file3', 'link1', 'link2', 'ping.js']); }); + it('supports withFileTypes for a deep directory', function () { + const p = path.join(asarDir, 'a.asar', 'dir3'); + const dirs = fs.readdirSync(p, { withFileTypes: true }); + for (const dir of dirs) { + expect(dir instanceof fs.Dirent).to.be.true(); + } + const names = dirs.map(a => a.name); + expect(names).to.deep.equal(['file1', 'file2', 'file3']); + }); + it('reads dirs from a linked dir', function () { const p = path.join(asarDir, 'a.asar', 'link2', 'link2'); const dirs = fs.readdirSync(p);