From cb945be0fca9023366416b3458316272a6599357 Mon Sep 17 00:00:00 2001 From: Trajan McGill Date: Wed, 10 Mar 2021 04:09:16 +0000 Subject: [PATCH] Make CreateSubdirectory() work in root directory Modify logic that ensures new path starts with current path, to allow case where current path has a trailing separator that cannot be trimmed (e.g. / or C:\). Change exception message when new path is not a sub-path of current path to clarify what it is saying. --- .../src/System/IO/DirectoryInfo.cs | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/libraries/System.IO.FileSystem/src/System/IO/DirectoryInfo.cs b/src/libraries/System.IO.FileSystem/src/System/IO/DirectoryInfo.cs index 80a44bd3ad926c..efb432d0a56841 100644 --- a/src/libraries/System.IO.FileSystem/src/System/IO/DirectoryInfo.cs +++ b/src/libraries/System.IO.FileSystem/src/System/IO/DirectoryInfo.cs @@ -74,20 +74,15 @@ public DirectoryInfo CreateSubdirectory(string path) string newPath = Path.GetFullPath(Path.Combine(FullPath, path)); - ReadOnlySpan trimmedNewPath = Path.TrimEndingDirectorySeparator(newPath.AsSpan()); - ReadOnlySpan trimmedCurrentPath = Path.TrimEndingDirectorySeparator(FullPath.AsSpan()); - // We want to make sure the requested directory is actually under the subdirectory. - if (trimmedNewPath.StartsWith(trimmedCurrentPath, PathInternal.StringComparison) - // Allow the exact same path, but prevent allowing "..\FooBar" through when the directory is "Foo" - && ((trimmedNewPath.Length == trimmedCurrentPath.Length) || PathInternal.IsDirectorySeparator(newPath[trimmedCurrentPath.Length]))) - { - FileSystem.CreateDirectory(newPath); - return new DirectoryInfo(newPath); - } - - // We weren't nested - throw new ArgumentException(SR.Format(SR.Argument_InvalidSubPath, path, FullPath), nameof(path)); + // Allow the exact same path, but prevent allowing "..\FooBar" through when the directory is "Foo" + string newPathWithTrailingSeparator = PathInternal.EnsureTrailingSeparator(newPath); + string currentPathWithTrailingSeparator = PathInternal.EnsureTrailingSeparator(FullPath); + if (!newPathWithTrailingSeparator.StartsWith(currentPathWithTrailingSeparator, PathInternal.StringComparison)) + throw new ArgumentException(SR.Format(SR.Argument_InvalidSubPath, newPath, FullPath), nameof(path)); + + FileSystem.CreateDirectory(newPath); + return new DirectoryInfo(newPath); } public void Create()