Browse Source

fix(asar): readdir(withFileTypes) fails on deep directory (#26865) (#27507)

when using readdirSync on a deep directory within the archive, the code fails to get the stats of child paths.

Co-authored-by: Avi Vahl <[email protected]>
Milan Burda 4 years ago
parent
commit
b90f5435a9
2 changed files with 22 additions and 2 deletions
  1. 12 2
      lib/common/asar.js
  2. 10 0
      spec/asar-spec.js

+ 12 - 2
lib/common/asar.js

@@ -597,7 +597,13 @@
       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: childPath });
+            nextTick(callback, [error]);
+            return;
+          }
           if (stats.isFile) {
             dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_FILE));
           } else if (stats.isDirectory) {
@@ -633,7 +639,11 @@
       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) {
+            throw createError(AsarError.NOT_FOUND, { asarPath, filePath: childPath });
+          }
           if (stats.isFile) {
             dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_FILE));
           } else if (stats.isDirectory) {

+ 10 - 0
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);