Example #1
0
        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));
        }