From 7c758f60abe52808fc0f3c7e1a38756cb86be8ae Mon Sep 17 00:00:00 2001 From: Ethan Arrowood Date: Sat, 12 Aug 2023 14:55:36 -0600 Subject: [PATCH] fs: fix readdir recursive sync & callback Refs: https://github.com/nodejs/node/issues/48640 PR-URL: https://github.com/nodejs/node/pull/48698 Fixes: https://github.com/nodejs/node/issues/48858 Reviewed-By: Ruben Bridgewater Reviewed-By: Benjamin Gruenbaum Reviewed-By: Moshe Atlow Reviewed-By: Yagiz Nizipli --- lib/fs.js | 13 ++++++++++--- test/sequential/test-fs-readdir-recursive.js | 2 ++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/fs.js b/lib/fs.js index 1f695f6b08540a..fd99fef03c5243 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -1430,14 +1430,21 @@ function readdirSyncRecursive(basePath, options) { ); handleErrorFromBinding(ctx); - for (let i = 0; i < readdirResult.length; i++) { - if (withFileTypes) { + if (withFileTypes) { + // Calling `readdir` with `withFileTypes=true`, the result is an array of arrays. + // The first array is the names, and the second array is the types. + // They are guaranteed to be the same length; hence, setting `length` to the length + // of the first array within the result. + const length = readdirResult[0].length; + for (let i = 0; i < length; i++) { const dirent = getDirent(path, readdirResult[0][i], readdirResult[1][i]); ArrayPrototypePush(readdirResults, dirent); if (dirent.isDirectory()) { ArrayPrototypePush(pathsQueue, pathModule.join(dirent.path, dirent.name)); } - } else { + } + } else { + for (let i = 0; i < readdirResult.length; i++) { const resultPath = pathModule.join(path, readdirResult[i]); const relativeResultPath = pathModule.relative(basePath, resultPath); const stat = binding.internalModuleStat(resultPath); diff --git a/test/sequential/test-fs-readdir-recursive.js b/test/sequential/test-fs-readdir-recursive.js index 3ced1434f303b7..1bb69f203ea526 100644 --- a/test/sequential/test-fs-readdir-recursive.js +++ b/test/sequential/test-fs-readdir-recursive.js @@ -131,9 +131,11 @@ function getDirentPath(dirent) { } function assertDirents(dirents) { + assert.strictEqual(dirents.length, expected.length); dirents.sort((a, b) => (getDirentPath(a) < getDirentPath(b) ? -1 : 1)); for (const [i, dirent] of dirents.entries()) { assert(dirent instanceof fs.Dirent); + assert.notStrictEqual(dirent.name, undefined); assert.strictEqual(getDirentPath(dirent), expected[i]); } }