Handle large limits for form keys and values #13719 (#15066)

This commit is contained in:
Chris Ross 2019-10-17 10:37:07 -07:00 committed by GitHub
parent 90b42ba099
commit 6d43b50183
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 2 deletions

View File

@ -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();
}

View File

@ -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)