withFileTypes has different behavior in fs.readdir when reading symbolic directories #52663
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 -> dir1
When 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
As described by class
Dirent
, type
"directory" and "symbolic link" of dirent
are mutually exclusive.
When {withFileTypes:false}
, is use
Line 1428 in 91dc8c9
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]
.