Keep Pipe readable after FormPipeReader error (#18939)

This commit is contained in:
Stephen Halter 2020-02-14 09:36:57 -08:00 committed by GitHub
parent 89ab8633a4
commit f3e2b4d4d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 5 deletions

View File

@ -92,7 +92,15 @@ namespace Microsoft.AspNetCore.WebUtilities
if (!buffer.IsEmpty)
{
ParseFormValues(ref buffer, ref accumulator, readResult.IsCompleted);
try
{
ParseFormValues(ref buffer, ref accumulator, readResult.IsCompleted);
}
catch
{
_pipeReader.AdvanceTo(buffer.Start);
throw;
}
}
if (readResult.IsCompleted)

View File

@ -94,21 +94,32 @@ namespace Microsoft.AspNetCore.WebUtilities
[Fact]
public async Task ReadFormAsync_ValueCountLimitExceeded_Throw()
{
var bodyPipe = await MakePipeReader("foo=1&baz=2&bar=3&baz=4&baf=5");
var content = "foo=1&baz=2&bar=3&baz=4&baf=5";
var bodyPipe = await MakePipeReader(content);
var exception = await Assert.ThrowsAsync<InvalidDataException>(
() => ReadFormAsync(new FormPipeReader(bodyPipe) { ValueCountLimit = 3 }));
Assert.Equal("Form value count limit 3 exceeded.", exception.Message);
// The body pipe is still readable and has not advanced.
var readResult = await bodyPipe.ReadAsync();
Assert.Equal(Encoding.UTF8.GetBytes(content), readResult.Buffer.ToArray());
}
[Fact]
public async Task ReadFormAsync_ValueCountLimitExceededSameKey_Throw()
{
var bodyPipe = await MakePipeReader("baz=1&baz=2&baz=3&baz=4");
var content = "baz=1&baz=2&baz=3&baz=4";
var bodyPipe = await MakePipeReader(content);
var exception = await Assert.ThrowsAsync<InvalidDataException>(
() => ReadFormAsync(new FormPipeReader(bodyPipe) { ValueCountLimit = 3 }));
Assert.Equal("Form value count limit 3 exceeded.", exception.Message);
// The body pipe is still readable and has not advanced.
var readResult = await bodyPipe.ReadAsync();
Assert.Equal(Encoding.UTF8.GetBytes(content), readResult.Buffer.ToArray());
}
[Fact]
@ -127,11 +138,16 @@ namespace Microsoft.AspNetCore.WebUtilities
[Fact]
public async Task ReadFormAsync_KeyLengthLimitExceeded_Throw()
{
var bodyPipe = await MakePipeReader("foo=1&baz12345678=2");
var content = "foo=1&baz12345678=2";
var bodyPipe = await MakePipeReader(content);
var exception = await Assert.ThrowsAsync<InvalidDataException>(
() => ReadFormAsync(new FormPipeReader(bodyPipe) { KeyLengthLimit = 10 }));
Assert.Equal("Form key length limit 10 exceeded.", exception.Message);
// The body pipe is still readable and has not advanced.
var readResult = await bodyPipe.ReadAsync();
Assert.Equal(Encoding.UTF8.GetBytes(content), readResult.Buffer.ToArray());
}
[Fact]
@ -150,11 +166,16 @@ namespace Microsoft.AspNetCore.WebUtilities
[Fact]
public async Task ReadFormAsync_ValueLengthLimitExceeded_Throw()
{
var bodyPipe = await MakePipeReader("foo=1&baz=12345678901");
var content = "foo=1&baz=12345678901";
var bodyPipe = await MakePipeReader(content);
var exception = await Assert.ThrowsAsync<InvalidDataException>(
() => ReadFormAsync(new FormPipeReader(bodyPipe) { ValueLengthLimit = 10 }));
Assert.Equal("Form value length limit 10 exceeded.", exception.Message);
// The body pipe is still readable and has not advanced.
var readResult = await bodyPipe.ReadAsync();
Assert.Equal(Encoding.UTF8.GetBytes(content), readResult.Buffer.ToArray());
}
// https://en.wikipedia.org/wiki/Percent-encoding