diff --git a/src/Http/WebUtilities/src/FormPipeReader.cs b/src/Http/WebUtilities/src/FormPipeReader.cs index b0a7d4684c..60f337757b 100644 --- a/src/Http/WebUtilities/src/FormPipeReader.cs +++ b/src/Http/WebUtilities/src/FormPipeReader.cs @@ -167,7 +167,7 @@ namespace Microsoft.AspNetCore.WebUtilities if (!isFinalBlock) { // Don't buffer indefinately - if (span.Length > KeyLengthLimit + ValueLengthLimit) + if ((uint)span.Length > (uint)KeyLengthLimit + (uint)ValueLengthLimit) { ThrowKeyOrValueTooLargeException(); } @@ -236,7 +236,7 @@ namespace Microsoft.AspNetCore.WebUtilities if (!isFinalBlock) { // Don't buffer indefinately - if ((sequenceReader.Consumed - consumedBytes) > KeyLengthLimit + ValueLengthLimit) + if ((uint)(sequenceReader.Consumed - consumedBytes) > (uint)KeyLengthLimit + (uint)ValueLengthLimit) { ThrowKeyOrValueTooLargeException(); } diff --git a/src/Http/WebUtilities/test/FormPipeReaderTests.cs b/src/Http/WebUtilities/test/FormPipeReaderTests.cs index 58d3af12d5..f0e806aae0 100644 --- a/src/Http/WebUtilities/test/FormPipeReaderTests.cs +++ b/src/Http/WebUtilities/test/FormPipeReaderTests.cs @@ -211,6 +211,28 @@ namespace Microsoft.AspNetCore.WebUtilities Assert.Equal("", dict["t"]); } + [Theory] + [MemberData(nameof(Encodings))] + public void TryParseFormValues_LimitsCanBeLarge(Encoding encoding) + { + var readOnlySequence = ReadOnlySequenceFactory.SingleSegmentFactory.CreateWithContent(encoding.GetBytes("foo=bar&baz=boo&t=")); + + KeyValueAccumulator accumulator = default; + + var formReader = new FormPipeReader(null, encoding); + formReader.KeyLengthLimit = int.MaxValue; + formReader.ValueLengthLimit = int.MaxValue; + formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: false); + formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true); + Assert.True(readOnlySequence.IsEmpty); + + Assert.Equal(3, accumulator.KeyCount); + var dict = accumulator.GetResults(); + Assert.Equal("bar", dict["foo"]); + Assert.Equal("boo", dict["baz"]); + Assert.Equal("", dict["t"]); + } + [Theory] [MemberData(nameof(Encodings))] public void TryParseFormValues_SplitAcrossSegmentsWorks(Encoding encoding) @@ -230,6 +252,28 @@ namespace Microsoft.AspNetCore.WebUtilities Assert.Equal("", dict["t"]); } + [Theory] + [MemberData(nameof(Encodings))] + public void TryParseFormValues_SplitAcrossSegmentsWorks_LimitsCanBeLarge(Encoding encoding) + { + var readOnlySequence = ReadOnlySequenceFactory.SegmentPerByteFactory.CreateWithContent(encoding.GetBytes("foo=bar&baz=boo&t=")); + + KeyValueAccumulator accumulator = default; + + var formReader = new FormPipeReader(null, encoding); + formReader.KeyLengthLimit = int.MaxValue; + formReader.ValueLengthLimit = int.MaxValue; + formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: false); + formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true); + Assert.True(readOnlySequence.IsEmpty); + + Assert.Equal(3, accumulator.KeyCount); + var dict = accumulator.GetResults(); + Assert.Equal("bar", dict["foo"]); + Assert.Equal("boo", dict["baz"]); + Assert.Equal("", dict["t"]); + } + [Theory] [MemberData(nameof(Encodings))] public void TryParseFormValues_MultiSegmentWithArrayPoolAcrossSegmentsWorks(Encoding encoding)