Commit bf152e63 authored by Dominik Charousset's avatar Dominik Charousset

Merge pull request #1022

parents 0c5ed145 5c6831ab
...@@ -69,7 +69,8 @@ void read_uri_percent_encoded(State& ps, std::string& str) { ...@@ -69,7 +69,8 @@ void read_uri_percent_encoded(State& ps, std::string& str) {
} }
inline bool uri_unprotected_char(char c) { inline bool uri_unprotected_char(char c) {
return in_whitelist(alphanumeric_chars, c) || in_whitelist("-._~", c); // Consider valid characters not explicitly stated as reserved as unreserved.
return isprint(c) && !in_whitelist(":/?#[]@!$&'()*+,;=<>", c);
} }
// clang-format off // clang-format off
...@@ -129,7 +130,9 @@ void read_uri(State& ps, Consumer&& consumer) { ...@@ -129,7 +130,9 @@ void read_uri(State& ps, Consumer&& consumer) {
return res; return res;
}; };
// Allowed character sets. // Allowed character sets.
auto path_char = [](char c) { return uri_unprotected_char(c) || c == '/'; }; auto path_char = [](char c) {
return uri_unprotected_char(c) || c == '/' || c == ':';
};
// Utility setters for avoiding code duplication. // Utility setters for avoiding code duplication.
auto set_path = [&] { consumer.path(take_str()); }; auto set_path = [&] { consumer.path(take_str()); };
auto set_host = [&] { consumer.host(take_str()); }; auto set_host = [&] { consumer.host(take_str()); };
...@@ -161,6 +164,8 @@ void read_uri(State& ps, Consumer&& consumer) { ...@@ -161,6 +164,8 @@ void read_uri(State& ps, Consumer&& consumer) {
epsilon(read_path, any_char, str += '/') epsilon(read_path, any_char, str += '/')
} }
state(start_authority) { state(start_authority) {
// A third '/' skips the authority, e.g., "file:///".
transition(read_path, '/', str += '/')
read_next_char(read_authority, str) read_next_char(read_authority, str)
fsm_transition(read_ipv6_address(ps, ip_consumer), await_end_of_ipv6, '[') fsm_transition(read_ipv6_address(ps, ip_consumer), await_end_of_ipv6, '[')
} }
......
...@@ -28,6 +28,7 @@ namespace detail { ...@@ -28,6 +28,7 @@ namespace detail {
void append_percent_encoded(std::string& str, string_view x, bool is_path) { void append_percent_encoded(std::string& str, string_view x, bool is_path) {
for (auto ch : x) for (auto ch : x)
switch (ch) { switch (ch) {
case ':':
case '/': case '/':
if (is_path) { if (is_path) {
str += ch; str += ch;
...@@ -35,7 +36,6 @@ void append_percent_encoded(std::string& str, string_view x, bool is_path) { ...@@ -35,7 +36,6 @@ void append_percent_encoded(std::string& str, string_view x, bool is_path) {
} }
CAF_ANNOTATE_FALLTHROUGH; CAF_ANNOTATE_FALLTHROUGH;
case ' ': case ' ':
case ':':
case '?': case '?':
case '#': case '#':
case '[': case '[':
......
...@@ -289,6 +289,7 @@ CAF_TEST(from string) { ...@@ -289,6 +289,7 @@ CAF_TEST(from string) {
// all combinations of components // all combinations of components
ROUNDTRIP("http:file"); ROUNDTRIP("http:file");
ROUNDTRIP("http:foo-bar"); ROUNDTRIP("http:foo-bar");
ROUNDTRIP("http:foo:bar");
ROUNDTRIP("http:file?a=1&b=2"); ROUNDTRIP("http:file?a=1&b=2");
ROUNDTRIP("http:file#42"); ROUNDTRIP("http:file#42");
ROUNDTRIP("http:file?a=1&b=2#42"); ROUNDTRIP("http:file?a=1&b=2#42");
...@@ -359,12 +360,14 @@ CAF_TEST(from string) { ...@@ -359,12 +360,14 @@ CAF_TEST(from string) {
ROUNDTRIP("http://me@[::1]:80/file?a=1&b=2#42"); ROUNDTRIP("http://me@[::1]:80/file?a=1&b=2#42");
// percent encoding // percent encoding
ROUNDTRIP("hi%20there://it%27s@me%21/file%201#%5B42%5D"); ROUNDTRIP("hi%20there://it%27s@me%21/file%201#%5B42%5D");
ROUNDTRIP("file://localhost/tmp/test/test.{%3A04d}.exr");
} }
#undef ROUNDTRIP #undef ROUNDTRIP
CAF_TEST(empty components) { CAF_TEST(empty components) {
CAF_CHECK_EQUAL("foo:/"_u, "foo:/"); CAF_CHECK_EQUAL("foo:/"_u, "foo:/");
CAF_CHECK_EQUAL("foo:///"_u, "foo:/");
CAF_CHECK_EQUAL("foo:/#"_u, "foo:/"); CAF_CHECK_EQUAL("foo:/#"_u, "foo:/");
CAF_CHECK_EQUAL("foo:/?"_u, "foo:/"); CAF_CHECK_EQUAL("foo:/?"_u, "foo:/");
CAF_CHECK_EQUAL("foo:/?#"_u, "foo:/"); CAF_CHECK_EQUAL("foo:/?#"_u, "foo:/");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment