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.
// ? 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)]