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

Commit

Permalink
./ paths relative on page.
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanbrandenburg committed Apr 25, 2017
1 parent 2d2ed57 commit 42b988a
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 11 deletions.
9 changes: 8 additions & 1 deletion src/Microsoft.AspNetCore.Mvc.Core/Internal/ViewEnginePath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace Microsoft.AspNetCore.Mvc.Core.Internal
{
public static class ViewEnginePath
{
private const string CurrentDirectoryToken = ".";
private const string ParentDirectoryToken = "..";
private static readonly char[] _pathSeparators = new[] { '/', '\\' };

Expand Down Expand Up @@ -70,6 +71,11 @@ public static string ResolvePath(string path)
}
pathSegments.RemoveAt(pathSegments.Count - 1);
}
else if (segment.Equals(CurrentDirectoryToken, StringComparison.Ordinal))
{
// We already have the current directory
continue;
}
else
{
pathSegments.Add(segment);
Expand All @@ -89,7 +95,8 @@ public static string ResolvePath(string path)

private static bool RequiresPathResolution(string path)
{
return path.IndexOf(ParentDirectoryToken, StringComparison.Ordinal) != -1;
return path.IndexOf(ParentDirectoryToken, StringComparison.Ordinal) != -1 ||
path.IndexOf(CurrentDirectoryToken, StringComparison.Ordinal) != -1;
}
}
}
2 changes: 1 addition & 1 deletion src/Microsoft.AspNetCore.Mvc.Core/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,6 @@
<value>No page named '{0}' matches the supplied values.</value>
</data>
<data name="UrlHelper_RelativePagePathIsNotSupported" xml:space="preserve">
<value>The relative page path '{0}' can only can only be used while executing a Razor Page. Specify a root relative path with a leading '/' to generate a URL outside of a Razor Page.</value>
<value>The relative page path '{0}' can only be used while executing a Razor Page. Specify a root relative path with a leading '/' to generate a URL outside of a Razor Page.</value>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,63 @@ public async Task ExecuteResultAsync_PassesCorrectValuesToRedirect(bool permanen
httpResponse.Verify(r => r.Redirect(expectedUrl, permanentRedirect), Times.Exactly(1));
}

[Fact]
public async Task ExecuteResultAsync_LocalRelativePaths()
{
// Arrange
var httpContext = new DefaultHttpContext
{
RequestServices = CreateServices(),
};

var pageContext = new PageContext
{
HttpContext = httpContext,
RouteData = new RouteData(),
ActionDescriptor = new CompiledPageActionDescriptor(),
};

pageContext.RouteData.Values.Add("page", "/A/Redirecting/Page");

UrlRouteContext context = null;
var urlHelper = new Mock<IUrlHelper>();
urlHelper.SetupGet(h => h.ActionContext).Returns(pageContext);
urlHelper.Setup(h => h.RouteUrl(It.IsAny<UrlRouteContext>()))
.Callback((UrlRouteContext c) => context = c)
.Returns("some-value");
var values = new { test = "test-value" };
var result = new RedirectToPageResult("./", "page-handler", values, true, "test-fragment")
{
UrlHelper = urlHelper.Object,
Protocol = "ftp",
};

// Act
await result.ExecuteResultAsync(pageContext);

// Assert
Assert.NotNull(context);
Assert.Null(context.RouteName);
Assert.Collection(Assert.IsType<RouteValueDictionary>(context.Values),
value =>
{
Assert.Equal("test", value.Key);
Assert.Equal("test-value", value.Value);
},
value =>
{
Assert.Equal("page", value.Key);
Assert.Equal("/A/Redirecting", value.Value);
},
value =>
{
Assert.Equal("handler", value.Key);
Assert.Equal("page-handler", value.Value);
});
Assert.Equal("ftp", context.Protocol);
Assert.Equal("test-fragment", context.Fragment);
}

[Fact]
public async Task ExecuteResultAsync_WithAllParameters()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1518,7 +1518,7 @@ public void Page_Throws_IfRouteValueDoesNotIncludePageKey()

// Act & Assert
var ex = Assert.Throws<InvalidOperationException>(() => urlHelper.Object.Page(expected));
Assert.Equal($"The relative page path '{expected}' can only can only be used while executing a Razor Page. " +
Assert.Equal($"The relative page path '{expected}' can only be used while executing a Razor Page. " +
"Specify a root relative path with a leading '/' to generate a URL outside of a Razor Page.", ex.Message);
}

Expand Down
41 changes: 34 additions & 7 deletions test/Microsoft.AspNetCore.Mvc.FunctionalTests/RazorPagesTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,20 @@ public async Task RedirectToSibling_RedirectsToSubDirectory()
Assert.Equal(expected, response.Headers.Location.ToString());
}

[Fact]
public async Task RedirectToSibling_RedirectsToDotSlash()
{
// Arrange
var expected = "/Pages/Redirects/SubDir/SubDirPage";

// Act
var response = await Client.GetAsync("/Pages/Redirects/RedirectToSibling/RedirectToDotSlash");

// Assert
Assert.Equal(HttpStatusCode.Redirect, response.StatusCode);
Assert.Equal(expected, response.Headers.Location.ToString());
}

[Fact]
public async Task RedirectToSibling_RedirectsToParentDirectory()
{
Expand All @@ -940,8 +954,8 @@ public async Task RedirectToSibling_RedirectsToParentDirectory()
public async Task TagHelpers_SupportSiblingRoutes()
{
// Arrange
var expected =
@"<form method=""post"" action=""/Pages/TagHelper/CrossPost""></form>
var expected =
@"<form method=""post"" action=""/Pages/TagHelper/CrossPost""></form>
<a href=""/Pages/TagHelper/SelfPost/12"" />
<input type=""image"" formaction=""/Pages/TagHelper/CrossPost#my-fragment"" />";

Expand All @@ -956,8 +970,8 @@ public async Task TagHelpers_SupportSiblingRoutes()
public async Task TagHelpers_SupportSubDirectoryRoutes()
{
// Arrange
var expected =
@"<form method=""post"" action=""/Pages/TagHelper/SubDir/SubDirPage""></form>
var expected =
@"<form method=""post"" action=""/Pages/TagHelper/SubDir/SubDirPage""></form>
<a href=""/Pages/TagHelper/SubDir/SubDirPage/12"" />
<input type=""image"" formaction=""/Pages/TagHelper/SubDir/SubDirPage#my-fragment"" />";

Expand All @@ -972,16 +986,29 @@ public async Task TagHelpers_SupportSubDirectoryRoutes()
public async Task TagHelpers_SupportsPathNavigation()
{
// Arrange
var expected =
@"<form method=""post"" action=""/HelloWorld""></form>
var expected =
@"<form method=""post"" action=""/HelloWorld""></form>
<a href=""/Pages/Redirects/RedirectToIndex"" />
<input type=""image"" formaction=""/Pages/Admin#my-fragment"" />";

// Act
var response = await Client.GetStringAsync("/Pages/TagHelper/PathTraversalLinks");

// Assert
Assert.Equal(expected, response.Trim());
Assert.EndsWith(expected, response.Trim());
}

[Fact]
public async Task TagHelpers_SupportsRelativeNavigation()
{
// Arrange
var expected = @"<form method=""post"" action=""/Pages/TagHelper/SubDirectoryLinks""></form>";

// Act
var response = await Client.GetStringAsync("/Pages/TagHelper/PathTraversalLinks");

// Assert
Assert.StartsWith(expected, response.Trim());
}

private async Task AddAntiforgeryHeaders(HttpRequestMessage request)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1472,6 +1472,7 @@ public void GetAbsolutePath_ReturnsPagePathUnchanged_IfNotAPath(string executing
[InlineData("/Views/Home/Index.cshtml", "..\\Shared\\_Partial.cshtml")]
[InlineData("/Areas/MyArea/Views/Home/Index.cshtml", "../../../../Views/Shared/_Partial.cshtml")]
[InlineData("/Views/Accounts/Users.cshtml", "../Test/../Shared/_Partial.cshtml")]
[InlineData("Views/Accounts/Users.cshtml", "./../Shared/./_Partial.cshtml")]
public void GetAbsolutePath_ResolvesPathTraversals(string executingFilePath, string pagePath)
{
// Arrange
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@
public IActionResult OnGetRedirectToSubDir() => RedirectToPage("SubDir/SubDirPage");

public IActionResult OnGetRedirectToParent() => RedirectToPage("../Conventions/AuthFolder/Index");

public IActionResult OnGetRedirectToDotSlash() => RedirectToPage("./SubDir/SubDirPage");
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@page

<form method="post" asp-page="./SubDirectoryLinks" asp-antiforgery="false"></form>
<form method="post" asp-page="../../HelloWorld" asp-antiforgery="false"></form>
<a asp-page="../Redirects/Index" asp-route-handler="RedirectToIndex" />
<input type="image" asp-page="../Admin/Index" asp-fragment="my-fragment" />
<input type="image" asp-page="../Admin/Index" asp-fragment="my-fragment" />

0 comments on commit 42b988a

Please sign in to comment.