Skip to content

Commit

Permalink
Expand support of uri parser to some missing cases and a subset of re…
Browse files Browse the repository at this point in the history
…lative references
  • Loading branch information
Anilm3 committed Jun 17, 2024
1 parent 0678e68 commit 7fdef07
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 24 deletions.
24 changes: 6 additions & 18 deletions src/uri_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
/ path-absolute
/ path-rootless
/ path-empty
relative-ref = relative-part [ "?" query ] [ "#" fragment ]
relative-part = "//" authority path-abempty
/ path-absolute
/ path-noscheme -> Not supported
/ path-empty -> Not supported
scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
authority = [ userinfo "@" ] host [ ":" port ]
userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
Expand Down Expand Up @@ -68,7 +73,6 @@ enum class token_type {
ipv6address,
regname_or_ipv4address,
path,
path_no_authority,
query,
fragment,
};
Expand Down Expand Up @@ -172,26 +176,10 @@ std::optional<uri_decomposed> uri_parse(std::string_view uri)
i += 2;
} else {
// Otherwise we expect a path (path-absolute, path-rootless, path-empty)
expected_token = token_type::path_no_authority;
expected_token = token_type::path;
}
break;
}
case token_type::path_no_authority: {
auto token_begin = i;
// The path can be empty but we wouldn't be here...
while (i < uri.size()) {
const auto c = uri[i++];
if (!is_path_char(c) && c != '/') {
return std::nullopt;
}
}

decomposed.path_index = token_begin;
decomposed.path = uri.substr(token_begin, i - token_begin);

// We're done, nothing else to parse
return decomposed;
}
case token_type::authority: {
auto token_begin = i;
authority_end = uri.find_first_of("/?#", i);
Expand Down
78 changes: 72 additions & 6 deletions tests/uri_utils_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,7 @@ TEST(TestURI, SchemeAndPath)
}
}

TEST(TestURI, SchemeMalformedPath)
{
EXPECT_FALSE(ddwaf::uri_parse("file:[][][]"));
EXPECT_FALSE(ddwaf::uri_parse("file:?query"));
EXPECT_FALSE(ddwaf::uri_parse("file:#fragment"));
}
TEST(TestURI, SchemeMalformedPath) { EXPECT_FALSE(ddwaf::uri_parse("file:[][][]")); }

TEST(TestURI, SchemeHost)
{
Expand Down Expand Up @@ -178,6 +173,40 @@ TEST(TestURI, SchemeHost)
}
}

TEST(TestURI, SchemeQuery)
{
auto uri = ddwaf::uri_parse("http:?hello");
ASSERT_TRUE(uri);
EXPECT_STRV(uri->scheme, "http");
EXPECT_STRV(uri->authority.host, "");
EXPECT_TRUE(uri->authority.userinfo.empty());
EXPECT_TRUE(uri->authority.port.empty());
EXPECT_STRV(uri->query, "hello");
}

TEST(TestURI, SchemeFragment)
{
auto uri = ddwaf::uri_parse("http:#hello");
ASSERT_TRUE(uri);
EXPECT_STRV(uri->scheme, "http");
EXPECT_STRV(uri->authority.host, "");
EXPECT_TRUE(uri->authority.userinfo.empty());
EXPECT_TRUE(uri->authority.port.empty());
EXPECT_STRV(uri->fragment, "hello");
}

TEST(TestURI, SchemeQueryFragment)
{
auto uri = ddwaf::uri_parse("http:?hello#bye");
ASSERT_TRUE(uri);
EXPECT_STRV(uri->scheme, "http");
EXPECT_STRV(uri->authority.host, "");
EXPECT_TRUE(uri->authority.userinfo.empty());
EXPECT_TRUE(uri->authority.port.empty());
EXPECT_STRV(uri->query, "hello");
EXPECT_STRV(uri->fragment, "bye");
}

TEST(TestURI, SchemeIPv4Host)
{
auto uri = ddwaf::uri_parse("http://1.2.3.4");
Expand Down Expand Up @@ -602,4 +631,41 @@ TEST(TestURI, RelativeRefAbsolutePathQueryFragment)
EXPECT_STRV(uri->fragment, "f");
}

TEST(TestURI, RelativeRefQuery)
{
auto uri = ddwaf::uri_parse("/?hello");
ASSERT_TRUE(uri);
EXPECT_STRV(uri->scheme, "");
EXPECT_STRV(uri->authority.host, "");
EXPECT_TRUE(uri->authority.userinfo.empty());
EXPECT_TRUE(uri->authority.port.empty());
EXPECT_STRV(uri->path, "/");
EXPECT_STRV(uri->query, "hello");
}

TEST(TestURI, RelativeRefFragment)
{
auto uri = ddwaf::uri_parse("/#hello");
ASSERT_TRUE(uri);
EXPECT_STRV(uri->scheme, "");
EXPECT_STRV(uri->authority.host, "");
EXPECT_TRUE(uri->authority.userinfo.empty());
EXPECT_TRUE(uri->authority.port.empty());
EXPECT_STRV(uri->path, "/");
EXPECT_STRV(uri->fragment, "hello");
}

TEST(TestURI, RelativeRefQueryFragment)
{
auto uri = ddwaf::uri_parse("/?hello#bye");
ASSERT_TRUE(uri);
EXPECT_STRV(uri->scheme, "");
EXPECT_STRV(uri->authority.host, "");
EXPECT_TRUE(uri->authority.userinfo.empty());
EXPECT_TRUE(uri->authority.port.empty());
EXPECT_STRV(uri->path, "/");
EXPECT_STRV(uri->query, "hello");
EXPECT_STRV(uri->fragment, "bye");
}

} // namespace

0 comments on commit 7fdef07

Please sign in to comment.