Skip to content

Commit f5fa16e

Browse files
authored
Make HTTP/1.1 startline parsing "safe" (#20885)
1 parent 351359f commit f5fa16e

22 files changed

+542
-411
lines changed

src/Servers/Kestrel/Core/ref/Microsoft.AspNetCore.Server.Kestrel.Core.netcoreapp.cs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -227,21 +227,30 @@ public partial class HttpParser<TRequestHandler> where TRequestHandler : Microso
227227
public HttpParser() { }
228228
public HttpParser(bool showErrorDetails) { }
229229
public bool ParseHeaders(TRequestHandler handler, ref System.Buffers.SequenceReader<byte> reader) { throw null; }
230-
public bool ParseRequestLine(TRequestHandler handler, in System.Buffers.ReadOnlySequence<byte> buffer, out System.SequencePosition consumed, out System.SequencePosition examined) { throw null; }
230+
public bool ParseRequestLine(TRequestHandler handler, ref System.Buffers.SequenceReader<byte> reader) { throw null; }
231231
}
232232
public enum HttpScheme
233233
{
234234
Unknown = -1,
235235
Http = 0,
236236
Https = 1,
237237
}
238-
public enum HttpVersion
238+
public enum HttpVersion : sbyte
239239
{
240-
Unknown = -1,
241-
Http10 = 0,
242-
Http11 = 1,
243-
Http2 = 2,
244-
Http3 = 3,
240+
Unknown = (sbyte)-1,
241+
Http10 = (sbyte)0,
242+
Http11 = (sbyte)1,
243+
Http2 = (sbyte)2,
244+
Http3 = (sbyte)3,
245+
}
246+
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
247+
public partial struct HttpVersionAndMethod
248+
{
249+
private int _dummyPrimitive;
250+
public HttpVersionAndMethod(Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpMethod method, int methodEnd) { throw null; }
251+
public Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpMethod Method { get { throw null; } }
252+
public int MethodEnd { get { throw null; } }
253+
public Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpVersion Version { get { throw null; } set { } }
245254
}
246255
public partial interface IHttpHeadersHandler
247256
{
@@ -252,7 +261,16 @@ public partial interface IHttpHeadersHandler
252261
}
253262
public partial interface IHttpRequestLineHandler
254263
{
255-
void OnStartLine(Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpMethod method, Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpVersion version, System.Span<byte> target, System.Span<byte> path, System.Span<byte> query, System.Span<byte> customMethod, bool pathEncoded);
264+
void OnStartLine(Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpVersionAndMethod versionAndMethod, Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.TargetOffsetPathLength targetPath, System.Span<byte> startLine);
265+
}
266+
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
267+
public readonly partial struct TargetOffsetPathLength
268+
{
269+
private readonly int _dummyPrimitive;
270+
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]public TargetOffsetPathLength(int offset, int length, bool isEncoded) { throw null; }
271+
public bool IsEncoded { [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]get { throw null; } }
272+
public int Length { [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]get { throw null; } }
273+
public int Offset { [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]get { throw null; } }
256274
}
257275
}
258276
namespace Microsoft.AspNetCore.Server.Kestrel.Https

src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,10 +310,18 @@ private bool Read(ReadOnlySequence<byte> readableBuffer, PipeWriter writableBuff
310310
// _consumedBytes aren't tracked for trailer headers, since headers have separate limits.
311311
if (_mode == Mode.TrailerHeaders)
312312
{
313-
if (_context.TakeMessageHeaders(readableBuffer, trailers: true, out consumed, out examined))
313+
var reader = new SequenceReader<byte>(readableBuffer);
314+
if (_context.TakeMessageHeaders(ref reader, trailers: true))
314315
{
316+
examined = reader.Position;
315317
_mode = Mode.Complete;
316318
}
319+
else
320+
{
321+
examined = readableBuffer.End;
322+
}
323+
324+
consumed = reader.Position;
317325
}
318326

319327
return _mode == Mode.Complete;

0 commit comments

Comments
 (0)