diff --git a/src/Ramstack.FileSystem.Abstractions/VirtualPath.cs b/src/Ramstack.FileSystem.Abstractions/VirtualPath.cs index 6ecb3be..886d652 100644 --- a/src/Ramstack.FileSystem.Abstractions/VirtualPath.cs +++ b/src/Ramstack.FileSystem.Abstractions/VirtualPath.cs @@ -244,10 +244,10 @@ public static string Normalize(string path) // Unwind back to the last separator index = buffer[..index].LastIndexOf('/'); - // Path.GetFullPath in this case does not throw an exception, - // it simply clears out the buffer. + // If no separator is found, reset to start + // (mimics Path.GetFullPath behavior) if (index < 0) - Error_InvalidPath(); + index = 0; } else { diff --git a/tests/Ramstack.FileSystem.Abstractions.Tests/VirtualPathTests.cs b/tests/Ramstack.FileSystem.Abstractions.Tests/VirtualPathTests.cs index 5e67d4c..d9a751b 100644 --- a/tests/Ramstack.FileSystem.Abstractions.Tests/VirtualPathTests.cs +++ b/tests/Ramstack.FileSystem.Abstractions.Tests/VirtualPathTests.cs @@ -107,17 +107,17 @@ public bool IsNormalized(string path) => [TestCase("/home/../home/user//documents", "/home/user/documents")] [TestCase("/home/../home/user/../../home/config/documents", "/home/config/documents")] [TestCase("/home/../home/user/./.././.././home/config/documents", "/home/config/documents")] + [TestCase("..", "/")] + [TestCase("../..", "/")] + [TestCase("../../../", "/")] + [TestCase("/home/../..", "/")] + [TestCase("/home/../../..", "/")] public void Normalize(string path, string expected) { foreach (var p in GetPathVariations(path)) Assert.That(VirtualPath.Normalize(p),Is.EqualTo(expected)); } - [TestCase("..")] - [TestCase("/home/../..")] - public void Normalize_Error(string path) => - Assert.Throws(() => VirtualPath.Normalize(path)); - private static string[] GetPathVariations(string path) => [path, path.Replace('/', '\\')]; } diff --git a/tests/Ramstack.FileSystem.Specification.Tests/VirtualFileSystemSpecificationTests.cs b/tests/Ramstack.FileSystem.Specification.Tests/VirtualFileSystemSpecificationTests.cs index a2c8484..4f0e6b5 100644 --- a/tests/Ramstack.FileSystem.Specification.Tests/VirtualFileSystemSpecificationTests.cs +++ b/tests/Ramstack.FileSystem.Specification.Tests/VirtualFileSystemSpecificationTests.cs @@ -79,39 +79,6 @@ await fs.GetFilesAsync("/", "**").CountAsync(), } } - [Test] - [Order(-1001)] - [SuppressMessage("ReSharper", "AccessToDisposedClosure")] - public async Task FileTree_NavigateAboveRoot_ThrowsException() - { - using var fs = GetFileSystem(); - - Assert.Throws(() => fs.GetDirectory("..")); - Assert.Throws(() => fs.GetDirectory("/..")); - Assert.Throws(() => fs.GetDirectory("/././..")); - Assert.Throws(() => fs.GetFile("..")); - Assert.Throws(() => fs.GetFile("/..")); - Assert.Throws(() => fs.GetFile("/././..")); - - Assert.That( - await fs.GetFilesAsync("/", "**").CountAsync(), - Is.Not.Zero); - - await foreach (var node in fs.GetFileNodesAsync("/", "**")) - { - foreach (var path in GetPathsAboveRoot(node.FullName)) - { - Assert.Throws(() => - { - if (node is VirtualDirectory) - fs.GetDirectory(path); - else - fs.GetFile(path); - }); - } - } - } - [Test] public async Task Exists_ReturnsTrue_For_ExistingFile() { @@ -843,21 +810,4 @@ public void Directory_Readonly_Delete_ThrowsException_For_NonExistingDirectory() /// A object that points to the root of the test directory. /// protected abstract DirectoryInfo GetDirectoryInfo(); - - private static IEnumerable GetPathsAboveRoot(string path) - { - var segments = path.Split('/', StringSplitOptions.RemoveEmptyEntries); - - for (var n = 0; n <= segments.Length; n++) - { - var prefix = segments.Take(n).ToArray(); - var suffix = segments.Skip(n).ToArray(); - var parent = Enumerable.Repeat("..", n + 1).ToArray(); - var curdir = Enumerable.Repeat(".", n + 1).ToArray(); - - yield return "/" + string.Join("/", prefix.Concat(parent).Concat(suffix)); - yield return "/" + string.Join("/", prefix.Concat(curdir).Concat(parent).Concat(suffix)); - yield return "/" + string.Join("/", curdir.Concat(prefix).Concat(parent).Concat(suffix)); - } - } }