From bf95c946ec1f8f78a1581e725480fe1c64ee83b5 Mon Sep 17 00:00:00 2001 From: Fabien Barbier <8518235+GoldenCrystal@users.noreply.github.com> Date: Tue, 25 Jun 2019 16:27:24 +0200 Subject: [PATCH] Blazor: Decode URL segments in RouteContext (#8759) * Decode URL segments in RouteContext --- .../Components/src/Routing/RouteContext.cs | 9 +++++++-- .../Components/test/Routing/RouteTableTests.cs | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/Components/Components/src/Routing/RouteContext.cs b/src/Components/Components/src/Routing/RouteContext.cs index 4830249ecc..7de5f3c615 100644 --- a/src/Components/Components/src/Routing/RouteContext.cs +++ b/src/Components/Components/src/Routing/RouteContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -15,6 +15,11 @@ namespace Microsoft.AspNetCore.Components.Routing // This is a simplification. We are assuming there are no paths like /a//b/. A proper routing // implementation would be more sophisticated. Segments = path.Trim('/').Split(Separator, StringSplitOptions.RemoveEmptyEntries); + // Individual segments are URL-decoded in order to support arbitrary characters, assuming UTF-8 encoding. + for (int i = 0; i < Segments.Length; i++) + { + Segments[i] = Uri.UnescapeDataString(Segments[i]); + } } public string[] Segments { get; } @@ -23,4 +28,4 @@ namespace Microsoft.AspNetCore.Components.Routing public IDictionary Parameters { get; set; } } -} \ No newline at end of file +} diff --git a/src/Components/Components/test/Routing/RouteTableTests.cs b/src/Components/Components/test/Routing/RouteTableTests.cs index 830024940e..c2e34d4298 100644 --- a/src/Components/Components/test/Routing/RouteTableTests.cs +++ b/src/Components/Components/test/Routing/RouteTableTests.cs @@ -100,6 +100,20 @@ namespace Microsoft.AspNetCore.Components.Test.Routing Assert.NotNull(context.Handler); } + [Fact] + public void CanMatchEncodedSegments() + { + // Arrange + var routeTable = new TestRouteTableBuilder().AddRoute("/some/ünicõdē/🛣/").Build(); + var context = new RouteContext("/some/%C3%BCnic%C3%B5d%C4%93/%F0%9F%9B%A3"); + + // Act + routeTable.Route(context); + + // Assert + Assert.NotNull(context.Handler); + } + [Fact] public void DoesNotMatchIfSegmentsDontMatch() { @@ -155,6 +169,9 @@ namespace Microsoft.AspNetCore.Components.Test.Routing [Theory] [InlineData("/value1", "value1")] [InlineData("/value2/", "value2")] + [InlineData("/d%C3%A9j%C3%A0%20vu", "déjà vu")] + [InlineData("/d%C3%A9j%C3%A0%20vu/", "déjà vu")] + [InlineData("/d%C3%A9j%C3%A0+vu", "déjà+vu")] public void CanMatchParameterTemplate(string path, string expectedValue) { // Arrange