From bd71de131c384765b9240b7a54649e2c9258b133 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Sat, 8 May 2021 12:52:25 +0100 Subject: Changed to use span --- .../Middleware/UrlDecodeQueryFeature.cs | 21 +++++++----- .../Controllers/EncodedQueryStringTest.cs | 39 --------------------- tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj | 1 + .../Jellyfin.Server.Implementations.Tests.csproj | 1 + .../Middleware/EncodedQueryStringTest.cs | 40 ++++++++++++++++++++++ 5 files changed, 55 insertions(+), 47 deletions(-) delete mode 100644 tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs create mode 100644 tests/Jellyfin.Server.Implementations.Tests/Middleware/EncodedQueryStringTest.cs diff --git a/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs index 44b30baac0..c89a318e16 100644 --- a/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs +++ b/Jellyfin.Server/Middleware/UrlDecodeQueryFeature.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using System.Web; +using MediaBrowser.Common.Extensions; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; using Microsoft.Extensions.Primitives; @@ -61,19 +62,23 @@ namespace Jellyfin.Server.Middleware } var pairs = new Dictionary(); - var queryString = unencodedKey.Split('&', System.StringSplitOptions.RemoveEmptyEntries); + var queryString = unencodedKey.SpanSplit('&'); foreach (var pair in queryString) { - var item = pair.Split('=', System.StringSplitOptions.RemoveEmptyEntries); - if (item.Length > 0) - { - pairs.Add(item[0], new StringValues(item.Length == 2 ? item[1] : string.Empty)); - } - else + var item = pair.Split('='); + item.MoveNext(); + + var key = item.Current; + var val = item.MoveNext() ? item.Current : string.Empty; + if (key.Length == 0 && val.Length == 0) { - pairs.Add(pair, string.Empty); + // encoded is an equals. + pairs.Add(pair.ToString(), new StringValues(string.Empty)); + continue; } + + pairs.Add(key.ToString(), new StringValues(val.ToString())); } _store = new QueryCollection(pairs); diff --git a/tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs b/tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs deleted file mode 100644 index d6a423dcdd..0000000000 --- a/tests/Jellyfin.Api.Tests/Controllers/EncodedQueryStringTest.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Text; -using System.Threading.Tasks; -using Xunit; - -namespace Jellyfin.Api.Tests.Controllers -{ - /// - /// Defines the test for encoded querystrings in the url. - /// - public class EncodedQueryStringTest : IClassFixture - { - private readonly JellyfinApplicationFactory _factory; - - public EncodedQueryStringTest(JellyfinApplicationFactory factory) - { - _factory = factory; - } - - [Theory] - [InlineData("a=1&b=2&c=3", "a=1&b=2&c=3")] // won't be processed as there is more than 1. - [InlineData("a=1", "a=1")] // won't be processed as it has a value - [InlineData("%3D", "==")] // will decode with an empty string value '=' = ''. - [InlineData("a%3D1%26b%3D2%26c%3D3", "a=1&b=2&c=3")] // will be processed. - public async Task Ensure_Decoding_Of_Urls_Is_Working(string sourceUrl, string unencodedUrl) - { - var client = _factory.CreateClient(); - - var response = await client.GetAsync("Tests/UrlDecode?" + sourceUrl).ConfigureAwait(false); - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - string reply = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - Assert.Equal(unencodedUrl, reply); - } - } -} diff --git a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj index 397b863b70..e3577caeee 100644 --- a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj +++ b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj @@ -37,6 +37,7 @@ + diff --git a/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj b/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj index 27713d58a3..ccc18d6869 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj +++ b/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj @@ -42,6 +42,7 @@ + diff --git a/tests/Jellyfin.Server.Implementations.Tests/Middleware/EncodedQueryStringTest.cs b/tests/Jellyfin.Server.Implementations.Tests/Middleware/EncodedQueryStringTest.cs new file mode 100644 index 0000000000..e5865fb5ac --- /dev/null +++ b/tests/Jellyfin.Server.Implementations.Tests/Middleware/EncodedQueryStringTest.cs @@ -0,0 +1,40 @@ +using System; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using Jellyfin.Server.Integration.Tests; +using Xunit; + +namespace Jellyfin.Server.Implementations.Tests.Middleware +{ + /// + /// Defines the test for encoded querystrings in the url. + /// + public class EncodedQueryStringTest : IClassFixture + { + private readonly JellyfinApplicationFactory _factory; + + public EncodedQueryStringTest(JellyfinApplicationFactory factory) + { + _factory = factory; + } + + [Theory] + [InlineData("a=1&b=2&c=3", "a=1&b=2&c=3")] // won't be processed as there is more than 1. + [InlineData("a=1", "a=1")] // won't be processed as it has a value + [InlineData("%3D", "==")] // will decode with an empty string value '=' = ''. + [InlineData("a%3D1%26b%3D2%26c%3D3", "a=1&b=2&c=3")] // will be processed. + public async Task Ensure_Decoding_Of_Urls_Is_Working(string sourceUrl, string unencodedUrl) + { + var client = _factory.CreateClient(); + + var response = await client.GetAsync("Tests/UrlDecode?" + sourceUrl).ConfigureAwait(false); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + string reply = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + Assert.Equal(unencodedUrl, reply); + } + } +} -- cgit v1.2.3