Fix absolute path handling.
- Normalize paths to be absolute and to also use forward slashes. - Updated our `EnsureValidPath` method to be `NormalizeAndEnsureValidPath`. - Added tests to validate new `NormalizeAndEnsureValidPath`. - Updated existing tests to react to `NormalizeAndEnsureValidPath` correctly. #1106
This commit is contained in:
parent
72febdac64
commit
c07759996f
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
|
|
@ -25,7 +24,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(root));
|
||||
}
|
||||
|
||||
Root = root.TrimEnd('/', '\\');
|
||||
Root = root.Replace('\\', '/').TrimEnd('/');
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -36,10 +35,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
/// <inheritdoc />
|
||||
public override IEnumerable<RazorProjectItem> EnumerateItems(string basePath)
|
||||
{
|
||||
EnsureValidPath(basePath);
|
||||
|
||||
Debug.Assert(basePath.StartsWith("/"));
|
||||
var absoluteBasePath = Path.Combine(Root, basePath.Substring(1));
|
||||
var absoluteBasePath = NormalizeAndEnsureValidPath(basePath);
|
||||
|
||||
var directory = new DirectoryInfo(absoluteBasePath);
|
||||
if (!directory.Exists)
|
||||
|
|
@ -53,17 +49,38 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
{
|
||||
var relativePath = file.FullName.Substring(absoluteBasePath.Length).Replace(Path.DirectorySeparatorChar, '/');
|
||||
return new FileSystemRazorProjectItem(basePath, relativePath, file);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override RazorProjectItem GetItem(string path)
|
||||
{
|
||||
EnsureValidPath(path);
|
||||
var absolutePath = NormalizeAndEnsureValidPath(path);
|
||||
|
||||
Debug.Assert(path.StartsWith("/"));
|
||||
var absolutePath = Path.Combine(Root, path.Substring(1));
|
||||
return new FileSystemRazorProjectItem("/", path, new FileInfo(absolutePath));
|
||||
}
|
||||
|
||||
protected override string NormalizeAndEnsureValidPath(string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(path));
|
||||
}
|
||||
|
||||
var absolutePath = path;
|
||||
if (!absolutePath.StartsWith(Root, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (path[0] == '/' || path[0] == '\\')
|
||||
{
|
||||
path = path.Substring(1);
|
||||
}
|
||||
|
||||
absolutePath = Path.Combine(Root, path);
|
||||
}
|
||||
|
||||
absolutePath = absolutePath.Replace('\\', '/');
|
||||
|
||||
return absolutePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,8 +59,8 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
/// </remarks>
|
||||
public virtual IEnumerable<RazorProjectItem> FindHierarchicalItems(string basePath, string path, string fileName)
|
||||
{
|
||||
EnsureValidPath(basePath);
|
||||
EnsureValidPath(path);
|
||||
basePath = NormalizeAndEnsureValidPath(basePath);
|
||||
path = NormalizeAndEnsureValidPath(path);
|
||||
if (string.IsNullOrEmpty(fileName))
|
||||
{
|
||||
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(fileName));
|
||||
|
|
@ -109,7 +109,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
/// Performs validation for paths passed to methods of <see cref="RazorProject"/>.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to validate.</param>
|
||||
protected virtual void EnsureValidPath(string path)
|
||||
protected virtual string NormalizeAndEnsureValidPath(string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
|
|
@ -120,6 +120,8 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
{
|
||||
throw new ArgumentException(Resources.RazorProject_PathMustStartWithForwardSlash, nameof(path));
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution
|
||||
|
|
@ -12,6 +13,57 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
private static string TestFolder { get; } =
|
||||
Path.Combine(TestProject.GetProjectDirectory(), "TestFiles", "FileSystemRazorProject");
|
||||
|
||||
[Theory]
|
||||
[InlineData(null)]
|
||||
[InlineData("")]
|
||||
public void NormalizeAndEnsureValidPath_ThrowsIfPathIsNullOrEmpty(string path)
|
||||
{
|
||||
// Arrange
|
||||
var project = new TestFileSystemRazorProject("C:/some/test/path/root");
|
||||
|
||||
// Act and Assert
|
||||
ExceptionAssert.ThrowsArgumentNullOrEmptyString(() => project.NormalizeAndEnsureValidPath(path), "path");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NormalizeAndEnsureValidPath_NormalizesToAbsolutePath()
|
||||
{
|
||||
// Arrange
|
||||
var project = new TestFileSystemRazorProject("C:/some/test/path/root");
|
||||
|
||||
// Act
|
||||
var absolutePath = project.NormalizeAndEnsureValidPath("file.cshtml");
|
||||
|
||||
// Assert
|
||||
Assert.Equal("C:/some/test/path/root/file.cshtml", absolutePath);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NormalizeAndEnsureValidPath_NormalizesToAbsolutePathWithoutForwardSlash()
|
||||
{
|
||||
// Arrange
|
||||
var project = new TestFileSystemRazorProject("C:/some/test/path/root");
|
||||
|
||||
// Act
|
||||
var absolutePath = project.NormalizeAndEnsureValidPath("/file.cshtml");
|
||||
|
||||
// Assert
|
||||
Assert.Equal("C:/some/test/path/root/file.cshtml", absolutePath);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NormalizeAndEnsureValidPath_NormalizesToForwardSlashes()
|
||||
{
|
||||
// Arrange
|
||||
var project = new TestFileSystemRazorProject(@"C:\some\test\path\root");
|
||||
|
||||
// Act
|
||||
var absolutePath = project.NormalizeAndEnsureValidPath(@"something\file.cshtml");
|
||||
|
||||
// Assert
|
||||
Assert.Equal("C:/some/test/path/root/something/file.cshtml", absolutePath);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EnumerateItems_DiscoversAllCshtmlFiles()
|
||||
{
|
||||
|
|
@ -104,5 +156,14 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
// Assert
|
||||
Assert.False(file.Exists);
|
||||
}
|
||||
|
||||
private class TestFileSystemRazorProject : FileSystemRazorProject
|
||||
{
|
||||
public TestFileSystemRazorProject(string root) : base(root)
|
||||
{
|
||||
}
|
||||
|
||||
public new string NormalizeAndEnsureValidPath(string path) => base.NormalizeAndEnsureValidPath(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,30 +11,43 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
{
|
||||
public class RazorProjectTest
|
||||
{
|
||||
[Fact]
|
||||
public void NormalizeAndEnsureValidPath_DoesNotModifyPath()
|
||||
{
|
||||
// Arrange
|
||||
var project = new TestRazorProject(new Dictionary<string, RazorProjectItem>());
|
||||
|
||||
// Act
|
||||
var path = project.NormalizeAndEnsureValidPath("/Views/Home/Index.cshtml");
|
||||
|
||||
// Assert
|
||||
Assert.Equal("/Views/Home/Index.cshtml", path);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(null)]
|
||||
[InlineData("")]
|
||||
public void EnsureValidPath_ThrowsIfPathIsNullOrEmpty(string path)
|
||||
public void NormalizeAndEnsureValidPath_ThrowsIfPathIsNullOrEmpty(string path)
|
||||
{
|
||||
// Arrange
|
||||
var project = new TestRazorProject(new Dictionary<string, RazorProjectItem>());
|
||||
|
||||
// Act and Assert
|
||||
ExceptionAssert.ThrowsArgumentNullOrEmptyString(() => project.EnsureValidPath(path), "path");
|
||||
ExceptionAssert.ThrowsArgumentNullOrEmptyString(() => project.NormalizeAndEnsureValidPath(path), "path");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("foo")]
|
||||
[InlineData("~/foo")]
|
||||
[InlineData("\\foo")]
|
||||
public void EnsureValidPath_ThrowsIfPathDoesNotStartWithForwardSlash(string path)
|
||||
public void NormalizeAndEnsureValidPath_ThrowsIfPathDoesNotStartWithForwardSlash(string path)
|
||||
{
|
||||
// Arrange
|
||||
var project = new TestRazorProject(new Dictionary<string, RazorProjectItem>());
|
||||
|
||||
// Act and Assert
|
||||
ExceptionAssert.ThrowsArgument(
|
||||
() => project.EnsureValidPath(path),
|
||||
() => project.NormalizeAndEnsureValidPath(path),
|
||||
"path",
|
||||
"Path must begin with a forward slash '/'.");
|
||||
}
|
||||
|
|
@ -338,7 +351,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
return item;
|
||||
}
|
||||
|
||||
public new void EnsureValidPath(string path) => base.EnsureValidPath(path);
|
||||
public new string NormalizeAndEnsureValidPath(string path) => base.NormalizeAndEnsureValidPath(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue