-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Fix: Avoid throwing if a symbolic link cycle to itself is detected while enumerating #52749
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Tagging subscribers to this area: @carlossanlop Issue DetailsFixes #52746
|
adamsitnik
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, @carlossanlop thank you for adding the description and a lot of tests, it made the reviewing much easier for me!
| DirectoryInfo testDirectory = CreateDirectorySymbolicLinkToItself(); | ||
|
|
||
| // Windows differentiates between dir symlinks and file symlinks | ||
| int expected = PlatformDetection.IsWindows ? 1 : 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
very minor nit: since System.IO.FileSystem.Tests does not target older TFMs, you can use OperatingSystem.IsWindows()
| int expected = PlatformDetection.IsWindows ? 1 : 0; | |
| int expected = OperatingSystem.IsWindows() ? 1 : 0; |
| public void EnumerateFileSystemEntries_LinksWithCycles_ShouldNotThrow() | ||
| { | ||
| DirectoryInfo testDirectory = CreateDirectorySymbolicLinkToItself(); | ||
| Assert.Equal(1, Directory.EnumerateFileSystemEntries(testDirectory.FullName).Count()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: xUnit analyzer would suggest using Single: https://stackoverflow.com/a/46654308/5852046
| Assert.Equal(1, Directory.EnumerateFileSystemEntries(testDirectory.FullName).Count()); | |
| Assert.Single(Directory.EnumerateFileSystemEntries(testDirectory.FullName)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strangely, I did not get the suggestion. But I can change it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only thing I need to confirm is if calling Single will force the creation of the objects, like Count() does, so that the disk hit is performed. If it's some kind of lazy count, it won't work.
| // Skipping attributes would force a disk hit which enters the cyclic symlink | ||
| new EnumerationOptions(){ AttributesToSkip = 0 }); | ||
|
|
||
| Assert.Equal(1, enumerable.Count()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Assert.Equal(1, enumerable.Count()); | |
| Assert.Single(enumerable); |
src/libraries/System.IO.FileSystem/tests/Directory/SymbolicLinks.cs
Outdated
Show resolved
Hide resolved
jozkee
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Otherwise LGTM, thanks.
| { | ||
| public abstract class BaseSymbolicLinks : FileSystemTest | ||
| { | ||
| protected DirectoryInfo CreateDirectorySymbolicLinkToItself() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
| protected DirectoryInfo CreateDirectorySymbolicLinkToItself() | |
| protected DirectoryInfo CreateDirectoryContainingSymbolicLinkToItself() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| protected DirectoryInfo CreateDirectorySymbolicLinkToItself() | |
| protected DirectoryInfo CreateDirectoryContainingSelfReferencingSymbolicLink() |
src/libraries/System.IO.FileSystem/tests/Directory/SymbolicLinks.cs
Outdated
Show resolved
Hide resolved
| testDirectory.EnumerateDirectories("*", options).Count(); | ||
| testDirectory.GetDirectories("*", options).Count(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assert how many entries this gets.
|
@carlossanlop CI issues seem related to the tests you are adding: |
|
Could you please update the PR title to "Avoid throwing if a self symbolic link cycle is detected while enumerating" since the fix is only for |
|
@jozkee thanks for pointing out the CI failure. We cannot create symbolic links in WASM. Any test that attempts to create symbolic links, must run behind the condition @iSazonov I thought about your suggestion to rename the PR, but instead I thought of adding tests that also verify links to the parent directory. There is only one case that I didn't add: recursively enumerate folders inside a symbolic link that points to its parent folder, because that causes an infinite loop. I don't think this is a bug. We can discuss limiting the recursion levels like @jozkee did in System.Text.Json. |
…lFact/ConditionalTheory
| { | ||
| isSymlink = entry.IsSymbolicLink; | ||
| isDirectory = entry._status.IsDirectory(entry.FullPath); | ||
| // Need to fail silently in case we are enumerating |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand the comment... isn't all of this code about enumerating?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enumeration always goes through this path, yes. I do not know if in the future we will reach FileSystemEntry.Initialize another way.
Next time I touch this code, I can change the comment to // This call needs to fail silently.
Fixes #52746