Skip to content
This repository has been archived by the owner on Dec 19, 2018. It is now read-only.

Commit

Permalink
Fix absolute path handling.
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
NTaylorMullen committed Mar 22, 2017
1 parent 72febda commit c077599
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 18 deletions.
37 changes: 27 additions & 10 deletions src/Microsoft.AspNetCore.Razor.Evolution/FileSystemRazorProject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;

Expand All @@ -25,7 +24,7 @@ public FileSystemRazorProject(string root)
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(root));
}

Root = root.TrimEnd('/', '\\');
Root = root.Replace('\\', '/').TrimEnd('/');
}

/// <summary>
Expand All @@ -36,10 +35,7 @@ public FileSystemRazorProject(string root)
/// <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)
Expand All @@ -53,17 +49,38 @@ public override IEnumerable<RazorProjectItem> EnumerateItems(string basePath)
{
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;
}
}
}
8 changes: 5 additions & 3 deletions src/Microsoft.AspNetCore.Razor.Evolution/RazorProject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ public IEnumerable<RazorProjectItem> FindHierarchicalItems(string path, string f
/// </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));
Expand Down Expand Up @@ -109,7 +109,7 @@ public virtual IEnumerable<RazorProjectItem> FindHierarchicalItems(string basePa
/// 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))
{
Expand All @@ -120,6 +120,8 @@ protected virtual void EnsureValidPath(string path)
{
throw new ArgumentException(Resources.RazorProject_PathMustStartWithForwardSlash, nameof(path));
}

return path;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.IO;
using System.Linq;
using Microsoft.AspNetCore.Testing;
using Xunit;

namespace Microsoft.AspNetCore.Razor.Evolution
Expand All @@ -12,6 +13,57 @@ public class FileSystemRazorProjectTest
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()
{
Expand Down Expand Up @@ -104,5 +156,14 @@ public void GetItem_ReturnsNotFoundResult()
// Assert
Assert.False(file.Exists);
}

private class TestFileSystemRazorProject : FileSystemRazorProject
{
public TestFileSystemRazorProject(string root) : base(root)
{
}

public new string NormalizeAndEnsureValidPath(string path) => base.NormalizeAndEnsureValidPath(path);
}
}
}
23 changes: 18 additions & 5 deletions test/Microsoft.AspNetCore.Razor.Evolution.Test/RazorProjectTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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 '/'.");
}
Expand Down Expand Up @@ -338,7 +351,7 @@ public override RazorProjectItem GetItem(string path)
return item;
}

public new void EnsureValidPath(string path) => base.EnsureValidPath(path);
public new string NormalizeAndEnsureValidPath(string path) => base.NormalizeAndEnsureValidPath(path);
}
}
}

0 comments on commit c077599

Please sign in to comment.