Skip to content

Conversation

@Neo-vortex
Copy link
Contributor

@Neo-vortex Neo-vortex commented Nov 23, 2025

fixes #116087

Fix CreateSubdirectory failing for root directories

Summary

Fixes a bug where DirectoryInfo.CreateSubdirectory(path) incorrectly throws ArgumentException when called on root directory instances (e.g., C:\).

Problem

Path.TrimEndingDirectorySeparator preserves trailing separators for root paths to maintain valid path format. This causes the boundary validation logic to use an incorrect index when checking for directory separators.

Example failure:

var rootDir = new DirectoryInfo(@"C:\");
rootDir.CreateSubdirectory("test"); // Throws ArgumentException

The check at index [3] evaluates the character 't' instead of the separator '\' at index [2], causing validation to fail.

Solution

After calling Path.TrimEndingDirectorySeparator, explicitly check if trimmedCurrentPath still has a trailing separator (root directory case) and remove it manually before performing boundary validation.

if (trimmedCurrentPath.Length > 0 && 
    PathInternal.IsDirectorySeparator(trimmedCurrentPath[trimmedCurrentPath.Length - 1]))
{
    trimmedCurrentPath = trimmedCurrentPath.Slice(0, trimmedCurrentPath.Length - 1);
}

This ensures consistent behavior: trimmedCurrentPath never ends with a separator, making the boundary index check work correctly for all directory types.

Impact

  • Fixes: Root directory subdirectory creation (Windows: C:\, D:\, )
  • No breaking changes: Non-root directory behavior unchanged
  • Low risk: Localized change to validation logic only

Testing

  • Existing tests continue to pass (non-root directories)
  • Manual testing confirms fix for root directories:
  new DirectoryInfo(@"C:\").CreateSubdirectory("test");     // ✓ Works
  new DirectoryInfo(@"C:\Users").CreateSubdirectory("Docs"); // ✓ Still works

Path.TrimEndingDirectorySeparator preserves trailing separators for root
paths like "C:\" or "/", causing boundary validation to check the wrong
index. Added explicit trim of trailing separator from trimmedCurrentPath
to fix the boundary check for root directory cases.

Signed-off-by: Mohamadreza Nakhleh <[email protected]>
@github-actions github-actions bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Nov 23, 2025
@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Nov 23, 2025
@vcsjones vcsjones added area-System.IO and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Nov 23, 2025
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-io
See info in area-owners.md if you want to be subscribed.

@kasperk81
Copy link
Contributor

Example failure:

that can be a test case

Signed-off-by: Mohamadreza Nakhleh <[email protected]>
@Neo-vortex
Copy link
Contributor Author

I added a test
@kasperk81

@Neo-vortex
Copy link
Contributor Author

Neo-vortex commented Nov 25, 2025

it seems Linux is also effected.
this code fails with the same error without this PR

var dir = new DirectoryInfo("/");
dir.CreateSubdirectory("test");

I added a test for linux as well

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-System.IO community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DirectoryInfo.CreateSubdirectory fails when DirectoryInfo path is a root directory

3 participants