fix: CreateSubdirectory failing for root directories#121906
fix: CreateSubdirectory failing for root directories#121906jozkee merged 23 commits intodotnet:mainfrom
Conversation
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 <neo.vortex@pm.me>
Signed-off-by: Mohamadreza Nakhleh <neo.vortex@pm.me>
that can be a test case |
Signed-off-by: Mohamadreza Nakhleh <neo.vortex@pm.me>
|
I added a test |
Signed-off-by: Mohamadreza Nakhleh <neo.vortex@pm.me>
…ortex/runtime into fix-directory-creating-root-folder
|
it seems Linux is also effected. var dir = new DirectoryInfo("/");
dir.CreateSubdirectory("test");I added a test for linux as well |
Signed-off-by: Mohamadreza Nakhleh <neo.vortex@pm.me>
|
linux tests are failing because of permission. the fact that it is trying to create the folder but gets Permission denied is an indication that this PR also fixes linux. |
|
@vcsjones |
if only the newly added tests in PR are failing, then change them to:
both cases are acceptable, either original assert passed or the op failed because of access issue. other exceptions are unexpected and should fail. |
Signed-off-by: Mohamadreza Nakhleh <neo.vortex@pm.me>
src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/Directory/EnumerableTests.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/Directory/EnumerableTests.cs
Outdated
Show resolved
Hide resolved
…Directory/EnumerableTests.cs Co-authored-by: kasperk81 <83082615+kasperk81@users.noreply.github.com>
src/libraries/System.Private.CoreLib/src/System/IO/DirectoryInfo.cs
Outdated
Show resolved
Hide resolved
…fo.cs Co-authored-by: Jeremy Kuhne <jeremy.kuhne@microsoft.com>
revert back to the old approved logic
|
reverted back to the known good code |
f5e58fb to
214a18d
Compare
|
@Neo-vortex I pushed 214a18d to your branch to apply the feedback from @JeremyKuhne appropriately. What you were missing is that runtime/src/libraries/Common/src/System/IO/PathInternal.cs Lines 229 to 232 in 31c3ed9 In the case of |
LGTM |
src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/Directory/EnumerableTests.cs
Outdated
Show resolved
Hide resolved
Move the root directory CreateSubdirectory tests from EnumerableTests.cs to DirectoryInfo/CreateSubdirectory.cs per review feedback. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
/ba-g infra timeout on "android-arm64 Release AllSubsets_Mono_Smoke", passed on arm. |
fixes dotnet#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:** ```csharp 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. ```csharp 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: ```csharp new DirectoryInfo(@"C:\").CreateSubdirectory("test"); // ✓ Works new DirectoryInfo(@"C:\Users").CreateSubdirectory("Docs"); // ✓ Still works ``` --------- Signed-off-by: Mohamadreza Nakhleh <neo.vortex@pm.me> Co-authored-by: kasperk81 <83082615+kasperk81@users.noreply.github.com> Co-authored-by: David Cantú <dacantu@microsoft.com> Co-authored-by: Jeremy Kuhne <jeremy.kuhne@microsoft.com> Co-authored-by: Jeff Handley <jeffhandley@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
fixes #116087
Fix CreateSubdirectory failing for root directories
Summary
Fixes a bug where
DirectoryInfo.CreateSubdirectory(path)incorrectly throwsArgumentExceptionwhen called on root directory instances (e.g.,C:\).Problem
Path.TrimEndingDirectorySeparatorpreserves 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:
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 iftrimmedCurrentPathstill has a trailing separator (root directory case) and remove it manually before performing boundary validation.This ensures consistent behavior:
trimmedCurrentPathnever ends with a separator, making the boundary index check work correctly for all directory types.Impact
C:\,D:\, )Testing