From: Stephen Toub Date: Thu, 10 Oct 2019 10:03:29 +0000 (-0400) Subject: Remove unnecessary length restriction on Uri.Escape{Data/Uri}String (dotnet/corefx... X-Git-Tag: submit/tizen/20210909.063632~11031^2~322 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=08b76ee2b9d09a13adecccbc727f5c9f1b27b7f4;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Remove unnecessary length restriction on Uri.Escape{Data/Uri}String (dotnet/corefx#41686) * Remove unnecessary length restriction on Uri.Escape{Data/Uri}String * Address PR feedback Co-Authored-By: David Shulman Commit migrated from https://github.com/dotnet/corefx/commit/1d49632bc213416d27ed6c567fd8dd08e00170a1 --- diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/FormUrlEncodedContentTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/FormUrlEncodedContentTest.cs index fa505a0..be116ff 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/FormUrlEncodedContentTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/FormUrlEncodedContentTest.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; -using System.Linq; using System.IO; using System.Text; using System.Threading.Tasks; @@ -37,6 +36,17 @@ namespace System.Net.Http.Functional.Tests Assert.Equal(0, stream.Length); } + [Theory] + [InlineData('F', ushort.MaxValue + 10)] + [InlineData('/', ushort.MaxValue + 10)] + public async Task Ctor_LongSource_Succeed(char c, int length) + { + const string Key = "test"; + var value = new string(c, length); + var content = new FormUrlEncodedContent(new Dictionary { { Key, value } }); + Assert.Equal($"{Key}={Uri.EscapeDataString(value)}", await content.ReadAsStringAsync()); + } + [Fact] public async Task Ctor_OneEntry_SeparatedByEquals() { diff --git a/src/libraries/System.Private.Uri/src/System/UriHelper.cs b/src/libraries/System.Private.Uri/src/System/UriHelper.cs index cbb5046..b26c7b0 100644 --- a/src/libraries/System.Private.Uri/src/System/UriHelper.cs +++ b/src/libraries/System.Private.Uri/src/System/UriHelper.cs @@ -134,9 +134,6 @@ namespace System internal static unsafe char[]? EscapeString(string input, int start, int end, char[]? dest, ref int destPos, bool isUriString, char force1, char force2, char rsvd) { - if (end - start >= Uri.c_MaxUriBufferSize) - throw new UriFormatException(SR.net_uri_SizeLimit); - int i = start; int prevInputPos = start; byte* bytes = stackalloc byte[c_MaxUnicodeCharsReallocate * c_MaxUTF_8BytesPerUnicodeChar]; // 40*4=160 diff --git a/src/libraries/System.Private.Uri/tests/FunctionalTests/IriTest.cs b/src/libraries/System.Private.Uri/tests/FunctionalTests/IriTest.cs index 103e17e..99354ce 100644 --- a/src/libraries/System.Private.Uri/tests/FunctionalTests/IriTest.cs +++ b/src/libraries/System.Private.Uri/tests/FunctionalTests/IriTest.cs @@ -495,36 +495,24 @@ namespace System.PrivateUri.Tests { } } - [Fact] - public void Iri_ValidateVeryLongInputString_EscapeDataString() + [Theory] + [InlineData(maxUriLength)] + [InlineData(maxUriLength + 1)] + [InlineData(10 + ushort.MaxValue)] + public void Iri_ValidateVeryLongInputString_EscapeDataString(int length) { - string bigString1 = GetUnicodeString(0, maxUriLength, 1); - Assert.True(Uri.EscapeDataString(bigString1).Length > bigString1.Length); - - try - { - string bigString2 = GetUnicodeString(0, maxUriLength + 1, 1); - Uri.EscapeDataString(bigString2); - Assert.False(true, "Expected UriFormatException: Uri too large"); - } - catch (FormatException) - { } + string s = GetUnicodeString(0, length, 1); + Assert.InRange(Uri.EscapeDataString(s).Length, s.Length + 1, int.MaxValue); } - [Fact] - public void Iri_ValidateVeryLongInputString_EscapeUriString() + [Theory] + [InlineData(maxUriLength)] + [InlineData(maxUriLength + 1)] + [InlineData(10 + ushort.MaxValue)] + public void Iri_ValidateVeryLongInputString_EscapeUriString(int length) { - string bigString1 = GetUnicodeString(0, maxUriLength, 1); - Assert.True(Uri.EscapeUriString(bigString1).Length > bigString1.Length); - - try - { - string bigString2 = GetUnicodeString(0, maxUriLength + 1, 1); - Uri.EscapeUriString(bigString2); - Assert.False(true, "Expected UriFormatException: Uri too large"); - } - catch (FormatException) - { } + string s = GetUnicodeString(0, length, 1); + Assert.InRange(Uri.EscapeUriString(s).Length, s.Length + 1, int.MaxValue); } [Theory] diff --git a/src/libraries/System.Private.Uri/tests/FunctionalTests/UriEscapingTest.cs b/src/libraries/System.Private.Uri/tests/FunctionalTests/UriEscapingTest.cs index 05a3af5..87a81c3 100644 --- a/src/libraries/System.Private.Uri/tests/FunctionalTests/UriEscapingTest.cs +++ b/src/libraries/System.Private.Uri/tests/FunctionalTests/UriEscapingTest.cs @@ -2,8 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Text; using System.Common.Tests; +using System.Collections.Generic; +using System.Linq; +using System.Text; using Xunit; @@ -106,6 +108,26 @@ namespace System.PrivateUri.Tests } } + public static IEnumerable UriEscapeUnescapeDataString_Roundtrip_MemberData() + { + // Test the no-longer-existing "c_MaxUriBufferSize" limit of 0xFFF0, + // as well as lengths longer than the max Uri length of ushort.MaxValue. + foreach (int length in new[] { 1, 0xFFF0, 0xFFF1, ushort.MaxValue + 10 }) + { + yield return new object[] { new string('s', length), string.Concat(Enumerable.Repeat("s", length)) }; + yield return new object[] { new string('/', length), string.Concat(Enumerable.Repeat("%2F", length)) }; + } + } + + [Theory] + [MemberData(nameof(UriEscapeUnescapeDataString_Roundtrip_MemberData))] + public void UriEscapeUnescapeDataString_Roundtrip(string input, string expectedEscaped) + { + string output = Uri.EscapeDataString(input); + Assert.Equal(expectedEscaped, output); + Assert.Equal(input, Uri.UnescapeDataString(output)); + } + #endregion EscapeDataString #region UnescapeDataString @@ -286,6 +308,24 @@ namespace System.PrivateUri.Tests Assert.Equal(input, output); } + public static IEnumerable UriEscapingUriString_Long_MemberData() + { + // Test the no-longer-existing "c_MaxUriBufferSize" limit of 0xFFF0, + // as well as lengths longer than the max Uri length of ushort.MaxValue. + foreach (int length in new[] { 1, 0xFFF0, 0xFFF1, ushort.MaxValue + 10 }) + { + yield return new object[] { new string('s', length), string.Concat(Enumerable.Repeat("s", length)) }; + yield return new object[] { new string('<', length), string.Concat(Enumerable.Repeat("%3C", length)) }; + } + } + + [Theory] + [MemberData(nameof(UriEscapingUriString_Long_MemberData))] + public void UriEscapingUriString_Long_Escaped(string input, string expectedEscaped) + { + Assert.Equal(expectedEscaped, Uri.EscapeUriString(input)); + } + #endregion EscapeUriString #region AbsoluteUri escaping diff --git a/src/libraries/System.Runtime/tests/System/Uri.MethodsTests.cs b/src/libraries/System.Runtime/tests/System/Uri.MethodsTests.cs index aac30b3..241c420 100644 --- a/src/libraries/System.Runtime/tests/System/Uri.MethodsTests.cs +++ b/src/libraries/System.Runtime/tests/System/Uri.MethodsTests.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.Linq; using System.Runtime.InteropServices; using Xunit; @@ -421,10 +422,22 @@ namespace System.Tests } [Fact] + public void EscapeDataString_Long_Success() + { + string s; + const int LongCount = 65520 + 1; + + s = new string('a', LongCount); + Assert.Equal(s, Uri.EscapeDataString(s)); + + s = new string('/', LongCount); + Assert.Equal(string.Concat(Enumerable.Repeat("%2F", LongCount)), Uri.EscapeDataString(s)); + } + + [Fact] public void EscapeDataString_Invalid() { AssertExtensions.Throws("stringToEscape", () => Uri.EscapeDataString(null)); // StringToEscape is null - Assert.Throws(() => Uri.EscapeDataString(UriCreateStringTests.s_longString)); // StringToEscape is too long Assert.Throws(() => Uri.EscapeDataString("\uD800")); // Incomplete surrogate pair provided Assert.Throws(() => Uri.EscapeDataString("abc\uD800")); // Incomplete surrogate pair provided @@ -463,10 +476,22 @@ namespace System.Tests } [Fact] + public void EscapeUriString_Long_Success() + { + string s; + const int LongCount = 65520 + 1; + + s = new string('a', LongCount); + Assert.Equal(s, Uri.EscapeUriString(s)); + + s = new string('<', LongCount); + Assert.Equal(string.Concat(Enumerable.Repeat("%3C", LongCount)), Uri.EscapeUriString(s)); + } + + [Fact] public void EscapeUriString_Invalid() { AssertExtensions.Throws("stringToEscape", () => Uri.EscapeUriString(null)); // StringToEscape is null - Assert.Throws(() => Uri.EscapeUriString(UriCreateStringTests.s_longString)); // StringToEscape is too long Assert.Throws(() => Uri.EscapeUriString("\uD800")); // Incomplete surrogate pair provided Assert.Throws(() => Uri.EscapeUriString("abc\uD800")); // Incomplete surrogate pair provided