Skip to content

Commit f3e2b4d

Browse files
authored
Keep Pipe readable after FormPipeReader error (#18939)
1 parent 89ab863 commit f3e2b4d

File tree

2 files changed

+34
-5
lines changed

2 files changed

+34
-5
lines changed

src/Http/WebUtilities/src/FormPipeReader.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,15 @@ public async Task<Dictionary<string, StringValues>> ReadFormAsync(CancellationTo
9292

9393
if (!buffer.IsEmpty)
9494
{
95-
ParseFormValues(ref buffer, ref accumulator, readResult.IsCompleted);
95+
try
96+
{
97+
ParseFormValues(ref buffer, ref accumulator, readResult.IsCompleted);
98+
}
99+
catch
100+
{
101+
_pipeReader.AdvanceTo(buffer.Start);
102+
throw;
103+
}
96104
}
97105

98106
if (readResult.IsCompleted)

src/Http/WebUtilities/test/FormPipeReaderTests.cs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,21 +94,32 @@ public async Task ReadFormAsync_ValueCountLimitMet_Success()
9494
[Fact]
9595
public async Task ReadFormAsync_ValueCountLimitExceeded_Throw()
9696
{
97-
var bodyPipe = await MakePipeReader("foo=1&baz=2&bar=3&baz=4&baf=5");
97+
var content = "foo=1&baz=2&bar=3&baz=4&baf=5";
98+
var bodyPipe = await MakePipeReader(content);
9899

99100
var exception = await Assert.ThrowsAsync<InvalidDataException>(
100101
() => ReadFormAsync(new FormPipeReader(bodyPipe) { ValueCountLimit = 3 }));
101102
Assert.Equal("Form value count limit 3 exceeded.", exception.Message);
103+
104+
// The body pipe is still readable and has not advanced.
105+
var readResult = await bodyPipe.ReadAsync();
106+
Assert.Equal(Encoding.UTF8.GetBytes(content), readResult.Buffer.ToArray());
102107
}
103108

104109
[Fact]
105110
public async Task ReadFormAsync_ValueCountLimitExceededSameKey_Throw()
106111
{
107-
var bodyPipe = await MakePipeReader("baz=1&baz=2&baz=3&baz=4");
112+
var content = "baz=1&baz=2&baz=3&baz=4";
113+
var bodyPipe = await MakePipeReader(content);
108114

109115
var exception = await Assert.ThrowsAsync<InvalidDataException>(
110116
() => ReadFormAsync(new FormPipeReader(bodyPipe) { ValueCountLimit = 3 }));
111117
Assert.Equal("Form value count limit 3 exceeded.", exception.Message);
118+
119+
120+
// The body pipe is still readable and has not advanced.
121+
var readResult = await bodyPipe.ReadAsync();
122+
Assert.Equal(Encoding.UTF8.GetBytes(content), readResult.Buffer.ToArray());
112123
}
113124

114125
[Fact]
@@ -127,11 +138,16 @@ public async Task ReadFormAsync_KeyLengthLimitMet_Success()
127138
[Fact]
128139
public async Task ReadFormAsync_KeyLengthLimitExceeded_Throw()
129140
{
130-
var bodyPipe = await MakePipeReader("foo=1&baz12345678=2");
141+
var content = "foo=1&baz12345678=2";
142+
var bodyPipe = await MakePipeReader(content);
131143

132144
var exception = await Assert.ThrowsAsync<InvalidDataException>(
133145
() => ReadFormAsync(new FormPipeReader(bodyPipe) { KeyLengthLimit = 10 }));
134146
Assert.Equal("Form key length limit 10 exceeded.", exception.Message);
147+
148+
// The body pipe is still readable and has not advanced.
149+
var readResult = await bodyPipe.ReadAsync();
150+
Assert.Equal(Encoding.UTF8.GetBytes(content), readResult.Buffer.ToArray());
135151
}
136152

137153
[Fact]
@@ -150,11 +166,16 @@ public async Task ReadFormAsync_ValueLengthLimitMet_Success()
150166
[Fact]
151167
public async Task ReadFormAsync_ValueLengthLimitExceeded_Throw()
152168
{
153-
var bodyPipe = await MakePipeReader("foo=1&baz=12345678901");
169+
var content = "foo=1&baz=12345678901";
170+
var bodyPipe = await MakePipeReader(content);
154171

155172
var exception = await Assert.ThrowsAsync<InvalidDataException>(
156173
() => ReadFormAsync(new FormPipeReader(bodyPipe) { ValueLengthLimit = 10 }));
157174
Assert.Equal("Form value length limit 10 exceeded.", exception.Message);
175+
176+
// The body pipe is still readable and has not advanced.
177+
var readResult = await bodyPipe.ReadAsync();
178+
Assert.Equal(Encoding.UTF8.GetBytes(content), readResult.Buffer.ToArray());
158179
}
159180

160181
// https://en.wikipedia.org/wiki/Percent-encoding

0 commit comments

Comments
 (0)