-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
Filenames and directories truncated to 30 characters #2706
Comments
I see... I ... think... I see.. :P But if For the long-term record, a summary of the question:
And the answer:
So I guess we should be good to use 255 always, when Here's the actual documentation page on the registry key: Maximum Path Length Limitation And according to that doc page, when the registry key is enabled, the path length limitation is raised to 32,767. |
On Windows, perhaps since Windows 95, the maximum length of file names was 260 characters. For windows' special LongPaths setting, the limit ranks up to 32,767 characters (according to Microsoft documentation, untested). By looking up the original commit and issue (icsharpcode#2038), that introduced the 30 characters limit, it was not clear what reason was behind the limit. Related GitHub issue: icsharpcode#2706.
On Windows, perhaps since Windows 95, the maximum length of file names was 260 characters. For windows' special LongPaths setting, the limit ranks up to 32,767 characters (according to Microsoft documentation, untested). By looking up the original commit and issue (icsharpcode#2038), that introduced the 30 characters limit, it was not clear what reason was behind the limit. Related GitHub issue: icsharpcode#2706.
First of all this feature was added recently to Windows 10, not Windows 95 and later. Windows 10 Version 1607 (Anniversary Update), internal version 10.0.14393, released in 2016. I think you are confusing two things here: "path length" and "file/directory name length", or as it is called by Jeremy Kuhne: "segment length" (see also https://docs.microsoft.com/en-us/archive/blogs/jeremykuhne/net-4-6-2-and-long-paths-on-windows-10) Before the update a path was limited to 260 characters. After the update this limit was raised, I believe to 2^15 (~32 000), however ILSpy treats it as "infinite" hence uses However, the segment length is a filesystem limitation where a directory name or file name (NOT path) can only be up to 255 characters: See also #2567 (comment) Sorry, for sounding harsh and rude, however, you are not the first person to report the file name truncation as being buggy and wrong, when in fact there is no good alternative, and I am a bit fed up with having to state the same facts and limitations over and over again. Sorry! |
There are multiple types of long path support in Windows. The new variant (since Windows 10 Version 1607) only requires setting the registry key, nothing else. The program can just use normal paths. Since ILSpy doesn't use kernel path syntax, you will need to set the registry key to enable long path support. We didn't add the registry check for fun; users without the registry key set were reporting crashes due to the total path being too long, e.g. even on Windows 11: #2622 |
Ok, I got mixed up with the "segment" and "path" lengths. But still, 30 is too little for my use case. Windows 10, without I don't know how 30 was decided upon but it simply is not realistic. Perhaps you should, instead limit the file name length to 255 or 260 -and- also check if the full path exceeds the limit before truncating it? |
This statement from the very docs on the long path feature hints on a bit more limitation:
That could have been another reason 255 (neither 260) worked on Windows. It should instead be 260 - 12 = 248? I guess I can create a simple project and check that out. |
The problem is that we only limit individual segments, but would need to also limit the full path. But I think the upgrade to .NET 6 might save us here: Unlike .NET framework 4.x, the new .NET seems to internally convert normal paths to kernel paths: dotnet/corefx#3001 |
It will now use 258 as maximum path length in windows, and also 258 - 12 (246) for file name (12 stands for the 8.3 file name space reservation required). For now, we'll throw an exception as truncating file names should be avoided, and decide if specific settings to enable truncation should take place. Changes the fallover maximums to a smaller value yet being generous about the limits. Related GitHub issue: icsharpcode#2706.
This changes the ProjectWriter class so that files created by it are validated using DirectoryInfo and/or FileInfo classes. Also adjusts hardcoded path lengths to: - use actual maximum windows' LongPaths feature allows (32767), - specify exact path part character limit (258-12), which reserves characters for the 8.3 legacy file name format, - increases unsupported platforms' limit to 200 characters instead of 30 Now WholeProjectDecompiler class will always check for full path while trying to create files to properly validate maximum path length exceeds. The hardcoded maxPathLength value (258) was tested to its edge cases, in which Visual Studio 2022 would allow a value of up to 259, whereas Notepad++ and WordPad won't open files with paths that long. Arbitrary values would also work (as far as DirInfo doesn't throw an exception, but most Windows applications wouldn't be able to handle the files. Related GitHub issue: icsharpcode#2706.
Okay, I gave it another try, changing it to validate the full path, and expand the output path to absolute when the class is instanced. I have tested its edge cases on Windows without long path support and it worked like a charm. This approach would help me split the embedded resources also in paths, albeit this is very prone to errors, if it proves problematic... I'll create an issue for the embedded resources if I can't find an already open one. |
This changes the ProjectWriter class so that files created by it are validated using DirectoryInfo and/or FileInfo classes. Also adjusts hardcoded path lengths to: - use actual maximum windows' LongPaths feature allows (32767), - specify exact path part character limit (258-12), which reserves characters for the 8.3 legacy file name format, - increases unsupported platforms' limit to 200 characters instead of 30 Now WholeProjectDecompiler class will always check for full path while trying to create files to properly validate maximum path length exceeds. The hardcoded maxPathLength value (258) was tested to its edge cases, in which Visual Studio 2022 would allow a value of up to 259, whereas Notepad++ and WordPad won't open files with paths that long. Arbitrary values would also work (as far as DirInfo doesn't throw an exception, but most Windows applications wouldn't be able to handle the files. Related GitHub issue: icsharpcode#2706.
This removes the 30 character long file names truncating limitation by improving Windows checks against the path and adding another layer of validation to ensure the full path would produce reachable files on Windows. - Expands 'TargetDirectory' to absolute path using System.IO.DirectoryInfo - Replaces file writing calls with path validating helpers: - File.Copy => CopyFile - new FileStream => MakeFileStream - new StreamWriter => MakeStreamWriter - File.WriteAllBytes => WriteBytesTo - Directory.CreateDirectory => CreateDir This should avoid future changes from forgetting to validate the path. - Implements Validation that: - Requires rooted paths - Parses path using System.IO.FileSystemInfo - Computes Windows' 8.3 path space reservation while validating directories - Checks parsed path against hardcoded path limits from GetLongPathSupport() - Ensures the parsed path is within TargetDirectory (protects against '../' paths and Path.Combine with rooted paths) Related GitHub issue: icsharpcode#2706
This update might be working, yes, I get it to make longer paths without registry settings... The problem is that almost no other application can open those paths... So perhaps this should be something configurable. Regardless of that, just having the limitation up to ~250 characters, and no longer trimming file names with just 30 characters is a huge improvement that should work in most cases! |
This could be an interesting approach to get specific file system's path limit, once we already have the |
…cters. With the built-in support for long paths in .NET 6.0, we no longer need to check for the registry key. The only limitation that remains is maxSegmentLength, which seems to be 255 on all commonly used file systems/all platforms. Also there is no need to differentiate between Windows and other platforms. - Windows Explorer in Windows 10 seems to be fine with files generated by ILSpy that have names longer than 260 characters. - Notepad++ and other applications seem to use 8.3 path syntax to access the file. - Visual Studio 2022 does not like the long path names, affected users should raise an issue with MS. ILSpy generates proper paths.
…cters. With the built-in support for long paths in .NET 6.0, we no longer need to check for the registry key. The only limitation that remains is maxSegmentLength, which seems to be 255 on all commonly used file systems/all platforms. Also there is no need to differentiate between Windows and other platforms. - Windows Explorer in Windows 10 seems to be fine with files generated by ILSpy that have names longer than 260 characters. - Notepad++ and other applications seem to use 8.3 path syntax to access the file. - Visual Studio 2022 does not like the long path names, affected users should raise an issue with MS. ILSpy generates proper paths.
Input code
Just make a simple project with an embedded resource file name with more than 30 characters, example:
mylongfilenameherebuthereandherealso.txt
Erroneous output
The file will be output as:
mylongfilenameherebuthereandhe.txt
(if I counted right, 30 characters)Details
master
build workflow)This was also reproduced in 7.2.0.0.rc version of the
Our Linux/Mac/Windows ILSpy UI based on [Avalonia](http://www.avaloniaui.net/) - check out https://github.com/icsharpcode/AvaloniaILSpy
(found in README.mdAlso reproduced in the windows GUI I downloaded, version: ILSpy version 7.2.1.6856. (sorry, I'm not sure, was it from MS Store?.. not sure... it works better than AvalonUI one).
Besides embedded resource filenames, for instance, if we don't
--nested-directories
, and the namespace goes beyond 30 characters, the same happens to the output directory name: truncated at 30 characters. The actual namespace in the output file is complete.While all links in the end project works well, in case the project has a reference or path to that embedded resource (if using string/reflection for instance), that would break the decompiled code (thus I believe this is a bug).
The text was updated successfully, but these errors were encountered: