diff --git a/lib/fs.js b/lib/fs.js index 9d941dd65ab613..af72ac36144c55 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -1531,6 +1531,9 @@ function readdir(path, options, callback) { } if (options.recursive) { + // Make shallow copy to prevent mutating options from affecting results + options = copyObject(options); + readdirRecursive(path, options, callback); return; } diff --git a/lib/internal/fs/promises.js b/lib/internal/fs/promises.js index 41be9a2a213b13..404f1f65edeb6c 100644 --- a/lib/internal/fs/promises.js +++ b/lib/internal/fs/promises.js @@ -944,6 +944,10 @@ async function readdirRecursive(originalPath, options) { async function readdir(path, options) { options = getOptions(options); + + // Make shallow copy to prevent mutating options from affecting results + options = copyObject(options); + path = getValidatedPath(path); if (options.recursive) { return readdirRecursive(path, options); diff --git a/test/parallel/test-fs-readdir-types.js b/test/parallel/test-fs-readdir-types.js index 3cc6b1cceff7fc..c6225c919e4a22 100644 --- a/test/parallel/test-fs-readdir-types.js +++ b/test/parallel/test-fs-readdir-types.js @@ -78,6 +78,22 @@ fs.readdir(readdirDir, { assertDirents(dirents); })().then(common.mustCall()); +// Check that mutating options doesn't affect results +(async () => { + const options = { withFileTypes: true }; + const direntsPromise = fs.promises.readdir(readdirDir, options); + options.withFileTypes = false; + assertDirents(await direntsPromise); +})().then(common.mustCall()); + +{ + const options = { recursive: true, withFileTypes: true }; + fs.readdir(readdirDir, options, common.mustSucceed((dirents) => { + assertDirents(dirents); + })); + options.withFileTypes = false; +} + // Check for correct types when the binding returns unknowns const UNKNOWN = constants.UV_DIRENT_UNKNOWN; const oldReaddir = binding.readdir;