public DirectoryInfo CreateSubdirectory(string path) { if (path == null) { throw new ArgumentNullException(nameof(path)); } if (PathInternal.IsEffectivelyEmpty(path.AsSpan())) { throw new ArgumentException(SR.Argument_PathEmpty, nameof(path)); } if (Path.IsPathRooted(path)) { throw new ArgumentException(SR.Arg_Path2IsRooted, nameof(path)); } string newPath = Path.GetFullPath(Path.Combine(FullPath, path)); ReadOnlySpan <char> trimmedNewPath = Path.TrimEndingDirectorySeparator(newPath.AsSpan()); ReadOnlySpan <char> 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)); }