diff --git a/src/libraries/System.Private.Uri/src/System/UriExt.cs b/src/libraries/System.Private.Uri/src/System/UriExt.cs index d2eecb162f5b3e..e7681c2a140a1e 100644 --- a/src/libraries/System.Private.Uri/src/System/UriExt.cs +++ b/src/libraries/System.Private.Uri/src/System/UriExt.cs @@ -548,6 +548,12 @@ public static bool TryUnescapeDataString(ReadOnlySpan charsToUnescape, Spa return false; } + if (destination.Length < indexOfFirstToUnescape) + { + charsWritten = 0; + return false; + } + // We may throw for very large inputs (when growing the ValueStringBuilder). scoped ValueStringBuilder vsb; diff --git a/src/libraries/System.Private.Uri/tests/FunctionalTests/UriEscapingTest.cs b/src/libraries/System.Private.Uri/tests/FunctionalTests/UriEscapingTest.cs index ea4be66631b546..fb5790b73f5a4d 100644 --- a/src/libraries/System.Private.Uri/tests/FunctionalTests/UriEscapingTest.cs +++ b/src/libraries/System.Private.Uri/tests/FunctionalTests/UriEscapingTest.cs @@ -300,6 +300,18 @@ static void ValidateUnescape(string input, string expectedOutput) } } + [Theory] + [InlineData("aa%", 0)] + [InlineData("aa%", 1)] + [InlineData("aaa%41", 0)] + [InlineData("aaa%41", 1)] + [InlineData("aaa%41", 2)] + public void TryUnescapeDataString_SmallDestination_ReturnsFalse(string input, int destinationLength) + { + Assert.False(Uri.TryUnescapeDataString(input, new char[destinationLength], out int charsWritten)); + Assert.Equal(0, charsWritten); + } + [Fact] public void UriEscapeUnescapeDataString_LongInputs() {