Skip to content

Commit 6d43b50

Browse files
authored
Handle large limits for form keys and values #13719 (#15066)
1 parent 90b42ba commit 6d43b50

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

src/Http/WebUtilities/src/FormPipeReader.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ private void ParseFormValuesFast(ReadOnlySpan<byte> span,
167167
if (!isFinalBlock)
168168
{
169169
// Don't buffer indefinately
170-
if (span.Length > KeyLengthLimit + ValueLengthLimit)
170+
if ((uint)span.Length > (uint)KeyLengthLimit + (uint)ValueLengthLimit)
171171
{
172172
ThrowKeyOrValueTooLargeException();
173173
}
@@ -236,7 +236,7 @@ private void ParseValuesSlow(
236236
if (!isFinalBlock)
237237
{
238238
// Don't buffer indefinately
239-
if ((sequenceReader.Consumed - consumedBytes) > KeyLengthLimit + ValueLengthLimit)
239+
if ((uint)(sequenceReader.Consumed - consumedBytes) > (uint)KeyLengthLimit + (uint)ValueLengthLimit)
240240
{
241241
ThrowKeyOrValueTooLargeException();
242242
}

src/Http/WebUtilities/test/FormPipeReaderTests.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,28 @@ public void TryParseFormValues_Works(Encoding encoding)
211211
Assert.Equal("", dict["t"]);
212212
}
213213

214+
[Theory]
215+
[MemberData(nameof(Encodings))]
216+
public void TryParseFormValues_LimitsCanBeLarge(Encoding encoding)
217+
{
218+
var readOnlySequence = ReadOnlySequenceFactory.SingleSegmentFactory.CreateWithContent(encoding.GetBytes("foo=bar&baz=boo&t="));
219+
220+
KeyValueAccumulator accumulator = default;
221+
222+
var formReader = new FormPipeReader(null, encoding);
223+
formReader.KeyLengthLimit = int.MaxValue;
224+
formReader.ValueLengthLimit = int.MaxValue;
225+
formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: false);
226+
formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true);
227+
Assert.True(readOnlySequence.IsEmpty);
228+
229+
Assert.Equal(3, accumulator.KeyCount);
230+
var dict = accumulator.GetResults();
231+
Assert.Equal("bar", dict["foo"]);
232+
Assert.Equal("boo", dict["baz"]);
233+
Assert.Equal("", dict["t"]);
234+
}
235+
214236
[Theory]
215237
[MemberData(nameof(Encodings))]
216238
public void TryParseFormValues_SplitAcrossSegmentsWorks(Encoding encoding)
@@ -230,6 +252,28 @@ public void TryParseFormValues_SplitAcrossSegmentsWorks(Encoding encoding)
230252
Assert.Equal("", dict["t"]);
231253
}
232254

255+
[Theory]
256+
[MemberData(nameof(Encodings))]
257+
public void TryParseFormValues_SplitAcrossSegmentsWorks_LimitsCanBeLarge(Encoding encoding)
258+
{
259+
var readOnlySequence = ReadOnlySequenceFactory.SegmentPerByteFactory.CreateWithContent(encoding.GetBytes("foo=bar&baz=boo&t="));
260+
261+
KeyValueAccumulator accumulator = default;
262+
263+
var formReader = new FormPipeReader(null, encoding);
264+
formReader.KeyLengthLimit = int.MaxValue;
265+
formReader.ValueLengthLimit = int.MaxValue;
266+
formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: false);
267+
formReader.ParseFormValues(ref readOnlySequence, ref accumulator, isFinalBlock: true);
268+
Assert.True(readOnlySequence.IsEmpty);
269+
270+
Assert.Equal(3, accumulator.KeyCount);
271+
var dict = accumulator.GetResults();
272+
Assert.Equal("bar", dict["foo"]);
273+
Assert.Equal("boo", dict["baz"]);
274+
Assert.Equal("", dict["t"]);
275+
}
276+
233277
[Theory]
234278
[MemberData(nameof(Encodings))]
235279
public void TryParseFormValues_MultiSegmentWithArrayPoolAcrossSegmentsWorks(Encoding encoding)

0 commit comments

Comments
 (0)