dotnet/runtime

FileNotFoundException with FileInfo.Length on Linux if binary filename contains a 0xDF-Byte

Open

#513 aperta il 4 dic 2019

Vedi su GitHub
 (11 commenti) (2 reazioni) (0 assegnatari)C# (5445 fork)batch import
area-System.IOenhancementhelp wanted

Metriche repository

Star
 (17.886 star)
Metriche merge PR
 (Merge medio 12g 11h) (661 PR mergiate in 30 g)

Descrizione

Special characters in Linux filenames can confuse the FileInfo.Length property, resulting in FileNotFoundException as shown in the attached test case , see also readme.txt inside the attached zip. SSharpException.zip

Edit: Another manifestation of this was reported in #76877. Those details are included below.

Description

If the path contains what I think is a blank character of some sort from classic Mac (I found it in an Apple archive), Directory.GetFiles will throw a DirectoryNotFoundException (I was also getting access denied on another machine but I can't reproduce that)

Reproduction Steps

It's difficult to put this into a Dockerfile or Bash script due to character escaping but the following should illustrate the issue

mkdir -p /tmp/test/''$'\240'hiddencharacter
dotnet new console
echo 'foreach (var dir in Directory.GetDirectories("/tmp/test")) Directory.GetFiles(dir);' > Program.cs
dotnet run

Unhandled exception. System.IO.DirectoryNotFoundException: Could not find a part of the path '/tmp/test/�hiddencharacter'.
   at System.IO.Enumeration.FileSystemEnumerator`1.CreateDirectoryHandle(String path, Boolean ignoreNotFound)
   at System.IO.Enumeration.FileSystemEnumerator`1.Init()
   at System.IO.Enumeration.FileSystemEnumerator`1..ctor(String directory, Boolean isNormalized, EnumerationOptions options)
   at System.IO.Enumeration.FileSystemEnumerable`1..ctor(String directory, FindTransform transform, EnumerationOptions options, Boolean isNormalized)
   at System.IO.Enumeration.FileSystemEnumerableFactory.UserFiles(String directory, String expression, EnumerationOptions options)
   at System.IO.Directory.InternalEnumeratePaths(String path, String searchPattern, SearchTarget searchTarget, EnumerationOptions options)
   at System.IO.Directory.GetFiles(String path, String searchPattern, EnumerationOptions enumerationOptions)
   at System.IO.Directory.GetFiles(String path)
   at Program.<Main>$(String[] args) in /src/Program.cs:line 1

Expected behavior

Files in directory are enumerated

Actual behavior

Exception

Regression?

Unknown, it fails with mono, too.

Known Workarounds

Unknown, I found this when using FileSystemEnumerable, my workaround is to test with Directory.GetFiles and then proceed with FileSystemEnumerable if there's no exception.

Configuration

Tested with: NET 6.0 docker image NET 7.0.100-rc.1.22431.12 on Debian bookworm

Other information

Setting LANG did not help

Guida contributor