-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Fix: Avoid throwing if a symbolic link cycle to itself is detected while enumerating #52749
Conversation
Tagging subscribers to this area: @carlossanlop Issue DetailsFixes #52746
|
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
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. |
b732bea
to
65ddfc3
Compare
…lFact/ConditionalTheory
@@ -45,15 +45,17 @@ namespace System.IO.Enumeration | |||
if (isUnknown) | |||
{ | |||
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