Skip to content

Commit

Permalink
Fix HttpListener path parsing for trailing % (#90028)
Browse files Browse the repository at this point in the history
  • Loading branch information
MihaZupan committed Aug 4, 2023
1 parent 91fae27 commit d66eb5c
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -179,15 +179,21 @@ private ParsingResult ParseRawPath(Encoding encoding)
current = _rawPath[index];
if (current == '%')
{
// Assert is enough, since http.sys accepted the request string already. This should never happen.
Debug.Assert(index + 2 < _rawPath.Length, "Expected >=2 characters after '%' (e.g. %2F)");
if (index + 2 >= _rawPath.Length)
{
// Not enough data for a percent encoded byte.
return ParsingResult.InvalidString;
}

index++;
current = _rawPath[index];
if (current == 'u' || current == 'U')
{
// We found "%u" which means, we have a Unicode code point of the form "%uXXXX".
Debug.Assert(index + 4 < _rawPath.Length, "Expected >=4 characters after '%u' (e.g. %u0062)");
if (index + 4 >= _rawPath.Length)
{
// Not enough data for "%uXXXX".
return ParsingResult.InvalidString;
}

// Decode the content of rawOctets into percent encoded UTF-8 characters and append them
// to requestUriString.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,14 @@ public static IEnumerable<object[]> InvalidRequest_TestData()

// ? prior to path and query. This may or may not fail, depending on the OS, but in either case it shouldn't crash.
yield return new object[] { "GET http://ab?cd{path} HTTP/1.1", null, null, null, "" };

// Path ending with an incomplete percent encoded byte or "%uXXXX"
yield return new object[] { "GET /foo/% HTTP/1.1", null, null, null, "" };
yield return new object[] { "GET /foo/%2 HTTP/1.1", null, null, null, "" };
yield return new object[] { "GET /foo/%u HTTP/1.1", null, null, null, "" };
yield return new object[] { "GET /foo/%uF HTTP/1.1", null, null, null, "" };
yield return new object[] { "GET /foo/%uFF HTTP/1.1", null, null, null, "" };
yield return new object[] { "GET /foo/%uFFF HTTP/1.1", null, null, null, "" };
}

[ActiveIssue("https://github.com/dotnet/runtime/issues/2284", TestRuntimes.Mono)]
Expand Down

0 comments on commit d66eb5c

Please sign in to comment.