-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
Problem
This recent PR introduced fixes for the ReadOnly
and Hidden
flags. While investigating the implementation of the recently approved symbolic link APIs, @jozkee and I discovered a potential regression for which we did not have any unit tests yet.
Repro steps
- In Unix, create a folder, then add a symbolic link with a cycle (for example, make it point to itself with
ln -s mylink mylink
). - Enumerate the files with
FileSystemEnumerable
(making sure the transform predicate returns a string with the path), or call one of theDirectory.Enumerate*
orDirectory.Get*
methods that return a list of strings with the paths.
Expected
The enumeration invocation is performed to its completion without throwing.
Actual
The enumeration invocation throws due to encountering a symbolic link with a cycle to itself.
Root cause
Before the PR, the method FileSystemEntry.Initialize
, which is a called by FileSystemEnumerator.MoveNext
, would silently skip the retrieval of the directory information via stat
or lstat
:
runtime/src/libraries/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEntry.Unix.cs
Line 51 in 2600044
&& Interop.Sys.Stat(entry.FullPath, out Interop.Sys.FileStatus targetStatus) >= 0) |
runtime/src/libraries/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEntry.Unix.cs
Line 63 in 2600044
&& (Interop.Sys.LStat(entry.FullPath, out Interop.Sys.FileStatus linkTargetStatus) >= 0)) |
Now, we are throwing because we are retrieving the directory information by calling the FileStatysm.IsDirectory
method, which internally throws unless otherwise specified:
runtime/src/libraries/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEntry.Unix.cs
Line 48 in 6a81cfa
isDirectory = entry._status.IsDirectory(entry.FullPath); |
runtime/src/libraries/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEntry.Unix.cs
Line 56 in 6a81cfa
isDirectory = entry._status.IsDirectory(entry.FullPath); |
Fix
Pass the continueOnError: true
argument to the IsDirectory
calls.
Add unit tests to verify enumeration of directories containing cyclic symbolic links is performed without problems.
Notes
-
There are some APIs that enumerate, then explicitly convert the
FileSystemEntry
instances toFileSystemInfo
s. Those cases should throw (this was the expected behavior before that PR), because that conversion forces astat
/lstat
to retrieve the file information, and that will fail due to the cycle. -
We may decide to change the throwing behavior the future. There's a request to detect symlink cycles and continue creating
FileSystemInfo
instances even with the detected error: Allow opting out of following directory links (reparse points / symlinks) during recursive file-system enumerations #52666