Use ascii decoding routine that disallows null chars (#1445)
* Use ascii decoding routine that disallows null chars - GetAsciiString() in newer corefxlab builds allows 0 (which is a valid ascii char). To avoid future regressions, GetAsciiStringNonNullCharacters() was added and used in place of GetAsciiString() when interpreting the request line and headers - Make GetAsciiStringNonNullCharacters return empty instead of null
This commit is contained in:
parent
20f75605ca
commit
da763b4873
|
|
@ -1228,7 +1228,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
|
||||||
if (needDecode)
|
if (needDecode)
|
||||||
{
|
{
|
||||||
// Read raw target before mutating memory.
|
// Read raw target before mutating memory.
|
||||||
rawTarget = target.GetAsciiString() ?? string.Empty;
|
rawTarget = target.GetAsciiStringNonNullCharacters();
|
||||||
|
|
||||||
// URI was encoded, unescape and then parse as utf8
|
// URI was encoded, unescape and then parse as utf8
|
||||||
int pathLength = UrlEncoder.Decode(path, path);
|
int pathLength = UrlEncoder.Decode(path, path);
|
||||||
|
|
@ -1237,7 +1237,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// URI wasn't encoded, parse as ASCII
|
// URI wasn't encoded, parse as ASCII
|
||||||
requestUrlPath = path.GetAsciiString() ?? string.Empty;
|
requestUrlPath = path.GetAsciiStringNonNullCharacters();
|
||||||
|
|
||||||
if (query.Length == 0)
|
if (query.Length == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -1247,21 +1247,21 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rawTarget = target.GetAsciiString() ?? string.Empty;
|
rawTarget = target.GetAsciiStringNonNullCharacters();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var normalizedTarget = PathNormalizer.RemoveDotSegments(requestUrlPath);
|
var normalizedTarget = PathNormalizer.RemoveDotSegments(requestUrlPath);
|
||||||
if (method != HttpMethod.Custom)
|
if (method != HttpMethod.Custom)
|
||||||
{
|
{
|
||||||
Method = HttpUtilities.MethodToString(method) ?? String.Empty;
|
Method = HttpUtilities.MethodToString(method) ?? string.Empty;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Method = customMethod.GetAsciiString() ?? string.Empty;
|
Method = customMethod.GetAsciiStringNonNullCharacters();
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryString = query.GetAsciiString() ?? string.Empty;
|
QueryString = query.GetAsciiStringNonNullCharacters();
|
||||||
RawTarget = rawTarget;
|
RawTarget = rawTarget;
|
||||||
HttpVersion = HttpUtilities.VersionToString(version);
|
HttpVersion = HttpUtilities.VersionToString(version);
|
||||||
|
|
||||||
|
|
@ -1289,7 +1289,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
|
||||||
{
|
{
|
||||||
RejectRequest(RequestRejectionReason.TooManyHeaders);
|
RejectRequest(RequestRejectionReason.TooManyHeaders);
|
||||||
}
|
}
|
||||||
var valueString = value.GetAsciiString() ?? string.Empty;
|
var valueString = value.GetAsciiStringNonNullCharacters();
|
||||||
|
|
||||||
FrameRequestHeaders.Append(name, valueString);
|
FrameRequestHeaders.Append(name, valueString);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,28 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public unsafe static string GetAsciiStringNonNullCharacters(this Span<byte> span)
|
||||||
|
{
|
||||||
|
if (span.IsEmpty)
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
var asciiString = new string('\0', span.Length);
|
||||||
|
|
||||||
|
fixed (char* output = asciiString)
|
||||||
|
fixed (byte* buffer = &span.DangerousGetPinnableReference())
|
||||||
|
{
|
||||||
|
// This version if AsciiUtilities returns null if there are any null (0 byte) characters
|
||||||
|
// in the string
|
||||||
|
if (!AsciiUtilities.TryGetAsciiString(buffer, output, span.Length))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return asciiString;
|
||||||
|
}
|
||||||
|
|
||||||
public static string GetAsciiStringEscaped(this Span<byte> span, int maxChars)
|
public static string GetAsciiStringEscaped(this Span<byte> span, int maxChars)
|
||||||
{
|
{
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue