diff --git a/src/Microsoft.AspNetCore.Http/Internal/RequestCookieCollection.cs b/src/Microsoft.AspNetCore.Http/Internal/RequestCookieCollection.cs index afc34489..1555b0b7 100644 --- a/src/Microsoft.AspNetCore.Http/Internal/RequestCookieCollection.cs +++ b/src/Microsoft.AspNetCore.Http/Internal/RequestCookieCollection.cs @@ -79,8 +79,8 @@ public static RequestCookieCollection Parse(IList values) for (var i = 0; i < cookies.Count; i++) { var cookie = cookies[i]; - var name = Uri.UnescapeDataString(cookie.Name.Replace('+', ' ')); - var value = Uri.UnescapeDataString(cookie.Value.Replace('+', ' ')); + var name = Uri.UnescapeDataString(cookie.Name); + var value = Uri.UnescapeDataString(cookie.Value); store[name] = value; } diff --git a/test/Microsoft.AspNetCore.Http.Tests/RequestCookiesCollectionTests.cs b/test/Microsoft.AspNetCore.Http.Tests/RequestCookiesCollectionTests.cs new file mode 100644 index 00000000..6af99b84 --- /dev/null +++ b/test/Microsoft.AspNetCore.Http.Tests/RequestCookiesCollectionTests.cs @@ -0,0 +1,46 @@ +// 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.Linq; +using Microsoft.AspNetCore.Http.Internal; +using Microsoft.Extensions.Primitives; +using Xunit; + +namespace Microsoft.AspNetCore.Http.Tests +{ + public class RequestCookiesCollectionTests + { + public static TheoryData UnEscapesKeyValues_Data + { + get + { + // key, value, expected + return new TheoryData + { + { "key=value", "key", "value" }, + { "key%2C=%21value", "key,", "!value" }, + { "ke%23y%2C=val%5Eue", "ke#y,", "val^ue" }, + { "key=value", "key", "value" }, + { "key%2C=%21value", "key,", "!value" }, + { "ke%23y%2C=val%5Eue", "ke#y,", "val^ue" }, + { "base64=QUI%2BREU%2FRw%3D%3D", "base64", "QUI+REU/Rw==" }, + { "base64=QUI+REU/Rw==", "base64", "QUI+REU/Rw==" }, + }; + } + } + + [Theory] + [MemberData(nameof(UnEscapesKeyValues_Data))] + public void UnEscapesKeyValues( + string input, + string expectedKey, + string expectedValue) + { + var cookies = RequestCookieCollection.Parse(new StringValues(input)); + + Assert.Equal(1, cookies.Count); + Assert.Equal(expectedKey, cookies.Keys.Single()); + Assert.Equal(expectedValue, cookies[expectedKey]); + } + } +} diff --git a/test/Microsoft.AspNetCore.Http.Tests/ResponseCookiesTest.cs b/test/Microsoft.AspNetCore.Http.Tests/ResponseCookiesTest.cs index 021f517b..f5625f0f 100644 --- a/test/Microsoft.AspNetCore.Http.Tests/ResponseCookiesTest.cs +++ b/test/Microsoft.AspNetCore.Http.Tests/ResponseCookiesTest.cs @@ -74,6 +74,7 @@ public static TheoryData EscapesKeyValuesBeforeSettingCookieData { "key", "value", _builderPool, "key=value" }, { "key,", "!value", _builderPool, "key%2C=%21value" }, { "ke#y,", "val^ue", _builderPool, "ke%23y%2C=val%5Eue" }, + { "base64", "QUI+REU/Rw==", _builderPool, "base64=QUI%2BREU%2FRw%3D%3D" }, }; } }