From 02e7e14782509c11e15cd559e5b07211600572ba Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Sun, 17 Apr 2022 08:26:29 -0700 Subject: [PATCH] Fix MapPath and UsePathBase's use of implicit PathStrings #41168 (#41215) --- .../src/Extensions/MapMiddleware.cs | 2 +- .../src/Extensions/UsePathBaseExtensions.cs | 4 ++-- .../src/Extensions/UsePathBaseMiddleware.cs | 2 +- .../test/MapPathMiddlewareTests.cs | 21 +++++++++++-------- .../test/UsePathBaseExtensionsTests.cs | 14 ++++++++++++- 5 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/Http/Http.Abstractions/src/Extensions/MapMiddleware.cs b/src/Http/Http.Abstractions/src/Extensions/MapMiddleware.cs index 63519cb1824f..382efd21c3a2 100644 --- a/src/Http/Http.Abstractions/src/Extensions/MapMiddleware.cs +++ b/src/Http/Http.Abstractions/src/Extensions/MapMiddleware.cs @@ -62,7 +62,7 @@ public Task Invoke(HttpContext context) return _next(context); } - private async Task InvokeCore(HttpContext context, string matchedPath, string remainingPath) + private async Task InvokeCore(HttpContext context, PathString matchedPath, PathString remainingPath) { var path = context.Request.Path; var pathBase = context.Request.PathBase; diff --git a/src/Http/Http.Abstractions/src/Extensions/UsePathBaseExtensions.cs b/src/Http/Http.Abstractions/src/Extensions/UsePathBaseExtensions.cs index f4d43e885ac8..b4e908854cc2 100644 --- a/src/Http/Http.Abstractions/src/Extensions/UsePathBaseExtensions.cs +++ b/src/Http/Http.Abstractions/src/Extensions/UsePathBaseExtensions.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Builder.Extensions; @@ -25,7 +25,7 @@ public static IApplicationBuilder UsePathBase(this IApplicationBuilder app, Path } // Strip trailing slashes - pathBase = pathBase.Value?.TrimEnd('/'); + pathBase = new PathString(pathBase.Value?.TrimEnd('/')); if (!pathBase.HasValue) { return app; diff --git a/src/Http/Http.Abstractions/src/Extensions/UsePathBaseMiddleware.cs b/src/Http/Http.Abstractions/src/Extensions/UsePathBaseMiddleware.cs index 2db00242f01a..0069bea7801f 100644 --- a/src/Http/Http.Abstractions/src/Extensions/UsePathBaseMiddleware.cs +++ b/src/Http/Http.Abstractions/src/Extensions/UsePathBaseMiddleware.cs @@ -53,7 +53,7 @@ public Task Invoke(HttpContext context) return _next(context); } - private async Task InvokeCore(HttpContext context, string matchedPath, string remainingPath) + private async Task InvokeCore(HttpContext context, PathString matchedPath, PathString remainingPath) { var originalPath = context.Request.Path; var originalPathBase = context.Request.PathBase; diff --git a/src/Http/Http.Abstractions/test/MapPathMiddlewareTests.cs b/src/Http/Http.Abstractions/test/MapPathMiddlewareTests.cs index 2882c92b63c8..1072477c8641 100644 --- a/src/Http/Http.Abstractions/test/MapPathMiddlewareTests.cs +++ b/src/Http/Http.Abstractions/test/MapPathMiddlewareTests.cs @@ -43,24 +43,27 @@ public void NullArguments_ArgumentNullException() } [Theory] - [InlineData("/foo", "", "/foo")] - [InlineData("/foo", "", "/foo/")] - [InlineData("/foo", "/Bar", "/foo")] - [InlineData("/foo", "/Bar", "/foo/cho")] - [InlineData("/foo", "/Bar", "/foo/cho/")] - [InlineData("/foo/cho", "/Bar", "/foo/cho")] - [InlineData("/foo/cho", "/Bar", "/foo/cho/do")] - public async Task PathMatchFunc_BranchTaken(string matchPath, string basePath, string requestPath) + [InlineData("/foo", "", "/foo", "/foo", "")] + [InlineData("/foo", "", "/foo/", "/foo", "/")] + [InlineData("/foo", "/Bar", "/foo", "/Bar/foo", "")] + [InlineData("/foo", "/Bar", "/foo/cho", "/Bar/foo", "/cho")] + [InlineData("/foo", "/Bar", "/foo/cho/", "/Bar/foo", "/cho/")] + [InlineData("/foo/cho", "/Bar", "/foo/cho", "/Bar/foo/cho", "")] + [InlineData("/foo/cho", "/Bar", "/foo/cho/do", "/Bar/foo/cho", "/do")] + [InlineData("/foo%42/cho", "/Bar%42", "/foo%42/cho/do%42", "/Bar%42/foo%42/cho", "/do%42")] + public async Task PathMatchFunc_BranchTaken(string matchPath, string basePath, string requestPath, string expectedPathBase, string expectedPath) { HttpContext context = CreateRequest(basePath, requestPath); var builder = new ApplicationBuilder(serviceProvider: null!); - builder.Map(matchPath, UseSuccess); + builder.Map(new PathString(matchPath), UseSuccess); var app = builder.Build(); await app.Invoke(context); Assert.Equal(200, context.Response.StatusCode); Assert.Equal(basePath, context.Request.PathBase.Value); Assert.Equal(requestPath, context.Request.Path.Value); + Assert.Equal(expectedPathBase, (string)context.Items["test.PathBase"]!); + Assert.Equal(expectedPath, context.Items["test.Path"]); } [Theory] diff --git a/src/Http/Http.Abstractions/test/UsePathBaseExtensionsTests.cs b/src/Http/Http.Abstractions/test/UsePathBaseExtensionsTests.cs index bf52b6530cdb..c01b6a735601 100644 --- a/src/Http/Http.Abstractions/test/UsePathBaseExtensionsTests.cs +++ b/src/Http/Http.Abstractions/test/UsePathBaseExtensionsTests.cs @@ -126,11 +126,23 @@ public Task PathBaseCanHaveUnicodeCharacters(string registeredPathBase, string p return TestPathBase(registeredPathBase, pathBase, requestPath, expectedPathBase, expectedPath); } + [Theory] + [InlineData("/b%42", "", "/b%42/something%42", "/b%42", "/something%42")] + [InlineData("/b%42", "", "/B%42/something%42", "/B%42", "/something%42")] + [InlineData("/b%42", "", "/b%42/Something%42", "/b%42", "/Something%42")] + [InlineData("/b%42", "/oldb%42", "/b%42/something%42", "/oldb%42/b%42", "/something%42")] + [InlineData("/b%42", "/oldb%42", "/b%42/Something%42", "/oldb%42/b%42", "/Something%42")] + [InlineData("/b%42", "/oldb%42", "/B%42/something%42", "/oldb%42/B%42", "/something%42")] + public Task PathBaseCanHavePercentCharacters(string registeredPathBase, string pathBase, string requestPath, string expectedPathBase, string expectedPath) + { + return TestPathBase(registeredPathBase, pathBase, requestPath, expectedPathBase, expectedPath); + } + private static async Task TestPathBase(string registeredPathBase, string pathBase, string requestPath, string expectedPathBase, string expectedPath) { HttpContext requestContext = CreateRequest(pathBase, requestPath); var builder = CreateBuilder() - .UsePathBase(registeredPathBase); + .UsePathBase(new PathString(registeredPathBase)); builder.Run(context => { context.Items["test.Path"] = context.Request.Path;