-
- Notifications
You must be signed in to change notification settings - Fork 33.8k
Description
Version
21.6.0
Platform
Linux 5.15.0-41-generic #44-Ubuntu x86_64 GNU/Linux
Subsystem
fs
What steps will reproduce the bug?
For the directory tree below
dir ├── dir1 │ └── 1.txt └── dir1_s -> dir1When using fs.readdir or fs.readdirSync to read the contents of dir, there is a difference in the number of contents outputted by the two:
const res = fs.readdirSync('./dir', {recursive: true, withFileTypes: true}); console.log(res); Output: // [ // Dirent { // name: 'dir1', // parentPath: './dir', // path: './dir', // [Symbol(type)]: 2 // }, // Dirent { // name: 'dir1_s', // parentPath: './dir', // path: './dir', // [Symbol(type)]: 3 // }, // Dirent { // name: '1.txt', // parentPath: 'dir/dir1', // path: 'dir/dir1', // [Symbol(type)]: 1 // } // ]const res = fs.readdirSync('./dir', {recursive: true, withFileTypes: false}); console.log(res); // Output: // [ 'dir1', 'dir1_s', 'dir1/1.txt', 'dir1_s/1.txt' ]So do fs.readdir.
How often does it reproduce? Is there a required condition?
Always
What is the expected behavior? Why is that the expected behavior?
No response
What do you see instead?
when withFileTypes: true, the directory entry dir1_s/1.txt haven't been outputted. However, I did not find any description in the documentation regarding the difference in handling symbolic directories between the two.
Additional information
I found that the reason is because the two use different conditions to determine whether to continue traversal. When {withFileTypes:true}. it use
Line 1420 in 91dc8c9
| if (dirent.isDirectory()) { |
As described by class
Dirent, type "directory" and "symbolic link" of dirent are mutually exclusive. When {withFileTypes:false}, is use
Line 1428 in 91dc8c9
| const stat = binding.internalModuleStat(resultPath); |
Contrary to {withFileTypes:true}, "directory" and "symbolic link" are compatible, and then allows traversal to continue into 1.txt after encountering the symbolic directory dir1_s.
I'm not sure if this is work as expected. If it's not, I believe maintaining consistency with the results of {withFileTypes: false} would be preferable, aligning with the result of find -L [path].