Escape reserved Windows device names in output file names#3776
Merged
Conversation
Windows maps CON, PRN, AUX, NUL, COM1-9 and LPT1-9 to devices -- on many builds even with an extension appended, so a type named Con made both whole-project export and the save dialog fail with IOException '\\.\Con'. CleanUpName only checked for reserved names after re-appending the file extension, where they never match, and the save-dialog default-name helpers did not check them at all. The escape appends the underscore to the base name (con_.txt, not con.txt_) because device-name parsing ignores everything after the first dot, and is applied per path segment so reserved directory names produced by namespaces are covered too. The ILSpy.Tests.Windows fixture verifies on a real Windows filesystem that the escaped names are creatable. Assisted-by: Claude:claude-fable-5:Claude Code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #3775.
CleanUpNameonly checkedIsReservedFileSystemNameafter re-appending the file extension, where it never matches, so a type namedConproducedCon.csboth in whole-project export and in the save dialog's default file name -- Windows resolves that to the\\.\CONdevice and the save fails with an IOException. Reserved directory segments (resource paths, namespace directories) slipped through the same way.CleanUpNamenow checks each segment as its whitelist loop closes it (separateAtDotsdot, path separator, end of input): if the segment's base name (the part before the first dot) is a reserved device name, an underscore is inserted before the dot (con.txt->con_.txt), since Windows device-name parsing ignores everything after the first dot.SaveCodeHelper,AssemblyTreeNode) now go throughWholeProjectDecompiler.CleanUpFileName, matching the WPF version, instead of ad-hoc invalid-char loops.ICSharpCode.Decompiler.Tests(all 22 reserved names x file/directory/path-segment variants) andILSpy.Tests;ILSpy.Tests.Windowsadditionally round-trips the sanitized names through a real Windows filesystem. The Windows fixture deliberately does not assert that the raw names fail to be created, because Windows 11 allows reserved names with extensions.Verified on Linux: full decompiler and UI test suites green. The
ILSpy.Tests.Windowsfixture still needs a run on a Windows machine.🤖 Generated with Claude Code