From 4bd51f2b49ad2950a8c01c47729493be3f0df278 Mon Sep 17 00:00:00 2001 From: Martin Trenkmann Date: Thu, 18 Oct 2018 15:33:42 +0200 Subject: [PATCH 01/19] Add functions is_unreserved and is_sub_delim --- include/network/uri/detail/encode.hpp | 30 +++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/include/network/uri/detail/encode.hpp b/include/network/uri/detail/encode.hpp index 794f3932..23161731 100644 --- a/include/network/uri/detail/encode.hpp +++ b/include/network/uri/detail/encode.hpp @@ -29,6 +29,36 @@ inline CharT hex_to_letter(CharT in) { return in; } +template +bool is_unreserved(charT in) { + return ((in >= 'a') && (in <= 'z')) || + ((in >= 'A') && (in <= 'Z')) || + ((in >= '0') && (in <= '9')) || + (in == '-') || + (in == '.') || + (in == '_') || + (in == '~'); +} + +template +bool is_sub_delim(charT in) { + switch (in) { + case '!': + case '$': + case '&': + case '\'': + case '(': + case ')': + case '*': + case '+': + case ',': + case ';': + case '='; + return true; + } + return false; +} + template void encode_char(charT in, OutputIterator &out, const char *ignore = "") { if (((in >= 'a') && (in <= 'z')) || From 6c6edb37a8ed520960657c198255409b219b4f08 Mon Sep 17 00:00:00 2001 From: Martin Trenkmann Date: Thu, 18 Oct 2018 15:35:38 +0200 Subject: [PATCH 02/19] Make use of is_unreserved() function --- include/network/uri/detail/encode.hpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/include/network/uri/detail/encode.hpp b/include/network/uri/detail/encode.hpp index 23161731..7a51cb47 100644 --- a/include/network/uri/detail/encode.hpp +++ b/include/network/uri/detail/encode.hpp @@ -61,13 +61,7 @@ bool is_sub_delim(charT in) { template void encode_char(charT in, OutputIterator &out, const char *ignore = "") { - if (((in >= 'a') && (in <= 'z')) || - ((in >= 'A') && (in <= 'Z')) || - ((in >= '0') && (in <= '9')) || - (in == '-') || - (in == '.') || - (in == '_') || - (in == '~')) { + if (is_unreserved(in)) { out++ = in; } else { auto first = ignore, last = ignore + std::strlen(ignore); From fc870e650051666022cf5def133fae8579219ab3 Mon Sep 17 00:00:00 2001 From: Martin Trenkmann Date: Thu, 18 Oct 2018 15:46:52 +0200 Subject: [PATCH 03/19] Add and use percent_encode() function --- include/network/uri/detail/encode.hpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/include/network/uri/detail/encode.hpp b/include/network/uri/detail/encode.hpp index 7a51cb47..2d415772 100644 --- a/include/network/uri/detail/encode.hpp +++ b/include/network/uri/detail/encode.hpp @@ -59,6 +59,13 @@ bool is_sub_delim(charT in) { return false; } +template +void percent_encode(charT in, OutputIterator &out) { + out++ = '%'; + out++ = hex_to_letter((in >> 4) & 0x0f); + out++ = hex_to_letter(in & 0x0f); +} + template void encode_char(charT in, OutputIterator &out, const char *ignore = "") { if (is_unreserved(in)) { @@ -68,9 +75,7 @@ void encode_char(charT in, OutputIterator &out, const char *ignore = "") { if (std::find(first, last, in) != last) { out++ = in; } else { - out++ = '%'; - out++ = hex_to_letter((in >> 4) & 0x0f); - out++ = hex_to_letter(in & 0x0f); + percent_encode(in, out); } } } From f937353aceb7f1f72397a41566ad5fc96e79e9e8 Mon Sep 17 00:00:00 2001 From: Martin Trenkmann Date: Thu, 18 Oct 2018 15:52:14 +0200 Subject: [PATCH 04/19] Add encode_pchar() function --- include/network/uri/detail/encode.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/network/uri/detail/encode.hpp b/include/network/uri/detail/encode.hpp index 2d415772..a26b6f95 100644 --- a/include/network/uri/detail/encode.hpp +++ b/include/network/uri/detail/encode.hpp @@ -80,6 +80,15 @@ void encode_char(charT in, OutputIterator &out, const char *ignore = "") { } } +template +void encode_pchar(charT in, OutputIterator &out) { + if (is_unreserved(in) || is_sub_delim(in) || (in == ':') || (in == '@')) { + out++ = in; + } else { + percent_encode(in, out); + } +} + template OutputIterator encode_user_info(InputIterator first, InputIterator last, OutputIterator out) { From 6d73cca99afbaf35418dd9fbe6ab761874dbf91e Mon Sep 17 00:00:00 2001 From: Martin Trenkmann Date: Thu, 18 Oct 2018 16:06:04 +0200 Subject: [PATCH 05/19] Add ignore parameter to encode_pchar() function --- include/network/uri/detail/encode.hpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/include/network/uri/detail/encode.hpp b/include/network/uri/detail/encode.hpp index a26b6f95..5318c670 100644 --- a/include/network/uri/detail/encode.hpp +++ b/include/network/uri/detail/encode.hpp @@ -81,11 +81,17 @@ void encode_char(charT in, OutputIterator &out, const char *ignore = "") { } template -void encode_pchar(charT in, OutputIterator &out) { +void encode_pchar(charT in, OutputIterator &out, const char *ignore = "") { if (is_unreserved(in) || is_sub_delim(in) || (in == ':') || (in == '@')) { out++ = in; } else { - percent_encode(in, out); + auto first = ignore; + auto last = ignore + std::strlen(ignore); + if (std::find(first, last, in) != last) { + out++ = in; + } else { + percent_encode(in, out); + } } } From 0fc353da235d926b6c43e056cd42f592c7d95f02 Mon Sep 17 00:00:00 2001 From: Martin Trenkmann Date: Thu, 18 Oct 2018 16:06:40 +0200 Subject: [PATCH 06/19] Make encode_query() make use of encode_pchar() function --- include/network/uri/detail/encode.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/network/uri/detail/encode.hpp b/include/network/uri/detail/encode.hpp index 5318c670..59bd136b 100644 --- a/include/network/uri/detail/encode.hpp +++ b/include/network/uri/detail/encode.hpp @@ -144,7 +144,7 @@ OutputIterator encode_query(InputIterator first, InputIterator last, OutputIterator out) { auto it = first; while (it != last) { - detail::encode_char(*it, out, "/.@&%;="); + detail::encode_pchar(*it, out, "/?"); ++it; } return out; From 7dae86ceb6aaf9fd35ccdbf607ed49791b8067c1 Mon Sep 17 00:00:00 2001 From: Martin Trenkmann Date: Thu, 18 Oct 2018 16:06:52 +0200 Subject: [PATCH 07/19] Fix typo --- include/network/uri/detail/encode.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/network/uri/detail/encode.hpp b/include/network/uri/detail/encode.hpp index 59bd136b..d1870163 100644 --- a/include/network/uri/detail/encode.hpp +++ b/include/network/uri/detail/encode.hpp @@ -53,7 +53,7 @@ bool is_sub_delim(charT in) { case '+': case ',': case ';': - case '='; + case '=': return true; } return false; From d0299000b4f4334c0965a6ae3dd962a8414d8e64 Mon Sep 17 00:00:00 2001 From: Martin Trenkmann Date: Thu, 18 Oct 2018 16:20:58 +0200 Subject: [PATCH 08/19] Adopt unit test to accepts fixed query encoding --- test/uri_encoding_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/uri_encoding_test.cpp b/test/uri_encoding_test.cpp index e37988c8..7eb095f4 100644 --- a/test/uri_encoding_test.cpp +++ b/test/uri_encoding_test.cpp @@ -54,7 +54,7 @@ TEST(uri_encoding_test, encode_query_iterator) { std::string instance; network::uri::encode_query(std::begin(unencoded), std::end(unencoded), std::back_inserter(instance)); - ASSERT_EQ("%21%23%24&%27%28%29%2A%2B%2C/%3A;=%3F@%5B%5D", instance); + ASSERT_EQ("!%23$&'()*+,/:;=?@%5B%5D", instance); } TEST(uri_encoding_test, encode_fragment_iterator) { From 1855a2e7d71890a35598a4f27657347d7ef4a5d0 Mon Sep 17 00:00:00 2001 From: Martin Trenkmann Date: Thu, 18 Oct 2018 16:22:21 +0200 Subject: [PATCH 09/19] Fix invalid escape sequence --- test/uri_encoding_test.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/uri_encoding_test.cpp b/test/uri_encoding_test.cpp index 7eb095f4..726b6d45 100644 --- a/test/uri_encoding_test.cpp +++ b/test/uri_encoding_test.cpp @@ -10,7 +10,7 @@ TEST(uri_encoding_test, encode_user_info_iterator) { - const std::string unencoded("!#$&\'()*+,/:;=?@[]"); + const std::string unencoded("!#$&'()*+,/:;=?@[]"); std::string instance; network::uri::encode_user_info(std::begin(unencoded), std::end(unencoded), std::back_inserter(instance)); @@ -18,7 +18,7 @@ TEST(uri_encoding_test, encode_user_info_iterator) { } TEST(uri_encoding_test, encode_host_iterator) { - const std::string unencoded("!#$&\'()*+,/:;=?@[]"); + const std::string unencoded("!#$&'()*+,/:;=?@[]"); std::string instance; network::uri::encode_host(std::begin(unencoded), std::end(unencoded), std::back_inserter(instance)); @@ -34,7 +34,7 @@ TEST(uri_encoding_test, encode_ipv6_host) { } TEST(uri_encoding_test, encode_port_iterator) { - const std::string unencoded("!#$&\'()*+,/:;=?@[]"); + const std::string unencoded("!#$&'()*+,/:;=?@[]"); std::string instance; network::uri::encode_port(std::begin(unencoded), std::end(unencoded), std::back_inserter(instance)); @@ -42,7 +42,7 @@ TEST(uri_encoding_test, encode_port_iterator) { } TEST(uri_encoding_test, encode_path_iterator) { - const std::string unencoded("!#$&\'()*+,/:;=?@[]"); + const std::string unencoded("!#$&'()*+,/:;=?@[]"); std::string instance; network::uri::encode_path(std::begin(unencoded), std::end(unencoded), std::back_inserter(instance)); @@ -50,7 +50,7 @@ TEST(uri_encoding_test, encode_path_iterator) { } TEST(uri_encoding_test, encode_query_iterator) { - const std::string unencoded("!#$&\'()*+,/:;=?@[]"); + const std::string unencoded("!#$&'()*+,/:;=?@[]"); std::string instance; network::uri::encode_query(std::begin(unencoded), std::end(unencoded), std::back_inserter(instance)); @@ -58,7 +58,7 @@ TEST(uri_encoding_test, encode_query_iterator) { } TEST(uri_encoding_test, encode_fragment_iterator) { - const std::string unencoded("!#$&\'()*+,/:;=?@[]"); + const std::string unencoded("!#$&'()*+,/:;=?@[]"); std::string instance; network::uri::encode_fragment(std::begin(unencoded), std::end(unencoded), std::back_inserter(instance)); @@ -70,7 +70,7 @@ TEST(uri_encoding_test, decode_iterator) { std::string instance; network::uri::decode(std::begin(encoded), std::end(encoded), std::back_inserter(instance)); - ASSERT_EQ("!#$&\'()*+,/:;=?@[]", instance); + ASSERT_EQ("!#$&'()*+,/:;=?@[]", instance); } TEST(uri_encoding_test, decode_iterator_error_1) { From 91054a13e2fd9ecdd53f382408ff1cb2501e2112 Mon Sep 17 00:00:00 2001 From: Martin Trenkmann Date: Thu, 18 Oct 2018 16:28:49 +0200 Subject: [PATCH 10/19] Adopt unit test to accepts fixed query encoding --- test/uri_builder_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/uri_builder_test.cpp b/test/uri_builder_test.cpp index 6bc8c8d7..f4658ca5 100644 --- a/test/uri_builder_test.cpp +++ b/test/uri_builder_test.cpp @@ -600,7 +600,7 @@ TEST(builder_test, build_uri_with_query_item_with_encoded_chars) .append_query_key_value_pair("a", "parameter with encoded chars!") .path("/") ; - ASSERT_EQ("http://www.example.com/?a=parameter%20with%20encoded%20chars%21", builder.uri().string()); + ASSERT_EQ("http://www.example.com/?a=parameter%20with%20encoded%20chars!", builder.uri().string()); } TEST(builder_test, build_uri_with_multiple_query_items_with_encoded_chars) { @@ -612,7 +612,7 @@ TEST(builder_test, build_uri_with_multiple_query_items_with_encoded_chars) { .append_query_key_value_pair("b", "second parameter with encoded chars!") .path("/") ; - ASSERT_EQ("http://www.example.com/?a=first%20parameter%20with%20encoded%20chars%21&b=second%20parameter%20with%20encoded%20chars%21", builder.uri().string()); + ASSERT_EQ("http://www.example.com/?a=first%20parameter%20with%20encoded%20chars!&b=second%20parameter%20with%20encoded%20chars!", builder.uri().string()); } TEST(builder_test, construct_from_existing_uri) { From 21e81a2df8663d696eb236689890d0e74ca88f80 Mon Sep 17 00:00:00 2001 From: Martin Trenkmann Date: Thu, 18 Oct 2018 16:51:58 +0200 Subject: [PATCH 11/19] Remove obsolete comment --- test/uri_builder_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/uri_builder_test.cpp b/test/uri_builder_test.cpp index f4658ca5..21c8a694 100644 --- a/test/uri_builder_test.cpp +++ b/test/uri_builder_test.cpp @@ -794,7 +794,7 @@ TEST(builder_test, construct_from_uri_bug_116) { const network::uri b("http://b.com"); a = b; - network::uri_builder ub(a); // ASAN reports heap-use-after-free here + network::uri_builder ub(a); const network::uri c(ub.uri()); ASSERT_FALSE(c.has_port()) << c.string(); } From a62fa3150682beba51802ff10f3c390d20a11375 Mon Sep 17 00:00:00 2001 From: Martin Trenkmann Date: Thu, 18 Oct 2018 17:15:40 +0200 Subject: [PATCH 12/19] Make encode_query() use encode_char() again --- include/network/uri/detail/encode.hpp | 31 +++++++-------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/include/network/uri/detail/encode.hpp b/include/network/uri/detail/encode.hpp index d1870163..ffc024c9 100644 --- a/include/network/uri/detail/encode.hpp +++ b/include/network/uri/detail/encode.hpp @@ -29,6 +29,13 @@ inline CharT hex_to_letter(CharT in) { return in; } +template +void percent_encode(charT in, OutputIterator &out) { + out++ = '%'; + out++ = hex_to_letter((in >> 4) & 0x0f); + out++ = hex_to_letter(in & 0x0f); +} + template bool is_unreserved(charT in) { return ((in >= 'a') && (in <= 'z')) || @@ -59,13 +66,6 @@ bool is_sub_delim(charT in) { return false; } -template -void percent_encode(charT in, OutputIterator &out) { - out++ = '%'; - out++ = hex_to_letter((in >> 4) & 0x0f); - out++ = hex_to_letter(in & 0x0f); -} - template void encode_char(charT in, OutputIterator &out, const char *ignore = "") { if (is_unreserved(in)) { @@ -80,21 +80,6 @@ void encode_char(charT in, OutputIterator &out, const char *ignore = "") { } } -template -void encode_pchar(charT in, OutputIterator &out, const char *ignore = "") { - if (is_unreserved(in) || is_sub_delim(in) || (in == ':') || (in == '@')) { - out++ = in; - } else { - auto first = ignore; - auto last = ignore + std::strlen(ignore); - if (std::find(first, last, in) != last) { - out++ = in; - } else { - percent_encode(in, out); - } - } -} - template OutputIterator encode_user_info(InputIterator first, InputIterator last, OutputIterator out) { @@ -144,7 +129,7 @@ OutputIterator encode_query(InputIterator first, InputIterator last, OutputIterator out) { auto it = first; while (it != last) { - detail::encode_pchar(*it, out, "/?"); + detail::encode_char(*it, out, "/.@%;="); ++it; } return out; From c4e798db4a6a02e70d2f3f71eb85aff5ae7d4e90 Mon Sep 17 00:00:00 2001 From: Martin Trenkmann Date: Thu, 18 Oct 2018 17:16:53 +0200 Subject: [PATCH 13/19] Add tests to check encoding of delimiters when used as query parameter values --- test/uri_builder_test.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/uri_builder_test.cpp b/test/uri_builder_test.cpp index 21c8a694..7dcd40b3 100644 --- a/test/uri_builder_test.cpp +++ b/test/uri_builder_test.cpp @@ -798,3 +798,33 @@ TEST(builder_test, construct_from_uri_bug_116) { const network::uri c(ub.uri()); ASSERT_FALSE(c.has_port()) << c.string(); } + +TEST(builder_test, append_query_key_value_pair_encodes_equals_sign) { + network::uri_builder ub(network::uri("http://example.com")); + ASSERT_NO_THROW(ub.append_query_key_value_pair("q", "=")); + ASSERT_EQ(network::string_view("%3D"), ub.uri().query_begin()->second); +} + +TEST(builder_test, append_query_key_value_pair_encodes_question_mark) { + network::uri_builder ub(network::uri("http://example.com")); + ASSERT_NO_THROW(ub.append_query_key_value_pair("q", "?")); + ASSERT_EQ(network::string_view("%3F"), ub.uri().query_begin()->second); +} + +TEST(builder_test, append_query_key_value_pair_encodes_number_sign) { + network::uri_builder ub(network::uri("http://example.com")); + ASSERT_NO_THROW(ub.append_query_key_value_pair("q", "#")); + ASSERT_EQ(network::string_view("%23"), ub.uri().query_begin()->second); +} + +TEST(builder_test, append_query_key_value_pair_encodes_percent_sign) { + network::uri_builder ub(network::uri("http://example.com")); + ASSERT_NO_THROW(ub.append_query_key_value_pair("q", "%")); + ASSERT_EQ(network::string_view("%25"), ub.uri().query_begin()->second); +} + +TEST(builder_test, append_query_key_value_pair_encodes_ampersand) { + network::uri_builder ub(network::uri("http://example.com")); + ASSERT_NO_THROW(ub.append_query_key_value_pair("q", "&")); + ASSERT_EQ(network::string_view("%26"), ub.uri().query_begin()->second); +} From 16801bb7ddb46c4031bdf49d44300f69f58375a0 Mon Sep 17 00:00:00 2001 From: Martin Trenkmann Date: Thu, 18 Oct 2018 17:43:48 +0200 Subject: [PATCH 14/19] Add encode_query_component() function --- include/network/uri/detail/encode.hpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/network/uri/detail/encode.hpp b/include/network/uri/detail/encode.hpp index ffc024c9..6dd50250 100644 --- a/include/network/uri/detail/encode.hpp +++ b/include/network/uri/detail/encode.hpp @@ -135,6 +135,17 @@ OutputIterator encode_query(InputIterator first, InputIterator last, return out; } +template +OutputIterator encode_query_component(InputIterator first, InputIterator last, + OutputIterator out) { + auto it = first; + while (it != last) { + detail::encode_char(*it, out); + ++it; + } + return out; +} + template OutputIterator encode_fragment(InputIterator first, InputIterator last, OutputIterator out) { From d2ba8529f57c0a15724609f02f3010d358e009c1 Mon Sep 17 00:00:00 2001 From: Martin Trenkmann Date: Thu, 18 Oct 2018 17:45:14 +0200 Subject: [PATCH 15/19] Change append_query_key_value_pair() to encode components separately --- include/network/uri/uri_builder.hpp | 16 +++++----------- src/uri_builder.cpp | 13 +++++++++++++ 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/include/network/uri/uri_builder.hpp b/include/network/uri/uri_builder.hpp index fd73e30e..a2c01d46 100644 --- a/include/network/uri/uri_builder.hpp +++ b/include/network/uri/uri_builder.hpp @@ -199,22 +199,15 @@ class uri_builder { uri_builder &clear_query(); /** - * \brief Adds a new query to the uri_builder. + * \brief Adds a new query key/value pair to the uri_builder. * \param key The query key. * \param value The query value. * \returns \c *this */ template - uri_builder &append_query_key_value_pair(const Key &key, const Value &value) { - if (!query_) { - query_ = string_type(); - } - else { - query_->append("&"); - } - string_type query_pair = detail::translate(key) + "=" + detail::translate(value); - network::uri::encode_query(std::begin(query_pair), std::end(query_pair), - std::back_inserter(*query_)); + uri_builder &append_query_key_value_pair(const Key &key, const Value &value) { + append_query_key_value_pair(detail::translate(key), + detail::translate(value)); return *this; } @@ -253,6 +246,7 @@ class uri_builder { void set_authority(string_type authority); void set_path(string_type path); void append_query(string_type query); + void append_query_key_value_pair(string_type key, string_type value); void set_fragment(string_type fragment); optional scheme_, user_info_, host_, port_, path_, query_, diff --git a/src/uri_builder.cpp b/src/uri_builder.cpp index 3ae64437..d50ac520 100644 --- a/src/uri_builder.cpp +++ b/src/uri_builder.cpp @@ -122,6 +122,19 @@ void uri_builder::append_query(string_type query) { std::back_inserter(*query_)); } +void uri_builder::append_query_key_value_pair(string_type key, string_type value) { + if (!query_) { + query_ = string_type(); + } else { + query_->push_back('&'); + } + detail::encode_query_component(std::begin(key), std::end(key), + std::back_inserter(*query_)); + query_->push_back('='); + detail::encode_query_component(std::begin(value), std::end(value), + std::back_inserter(*query_)); +} + uri_builder &uri_builder::clear_query() { query_ = network::nullopt; return *this; From 4c4c6b558e8f51d9773275add6e612e978989cc7 Mon Sep 17 00:00:00 2001 From: Martin Trenkmann Date: Thu, 18 Oct 2018 17:45:39 +0200 Subject: [PATCH 16/19] Roll back some previous changes --- test/uri_builder_test.cpp | 4 ++-- test/uri_encoding_test.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/uri_builder_test.cpp b/test/uri_builder_test.cpp index 7dcd40b3..68ed0107 100644 --- a/test/uri_builder_test.cpp +++ b/test/uri_builder_test.cpp @@ -600,7 +600,7 @@ TEST(builder_test, build_uri_with_query_item_with_encoded_chars) .append_query_key_value_pair("a", "parameter with encoded chars!") .path("/") ; - ASSERT_EQ("http://www.example.com/?a=parameter%20with%20encoded%20chars!", builder.uri().string()); + ASSERT_EQ("http://www.example.com/?a=parameter%20with%20encoded%20chars%21", builder.uri().string()); } TEST(builder_test, build_uri_with_multiple_query_items_with_encoded_chars) { @@ -612,7 +612,7 @@ TEST(builder_test, build_uri_with_multiple_query_items_with_encoded_chars) { .append_query_key_value_pair("b", "second parameter with encoded chars!") .path("/") ; - ASSERT_EQ("http://www.example.com/?a=first%20parameter%20with%20encoded%20chars!&b=second%20parameter%20with%20encoded%20chars!", builder.uri().string()); + ASSERT_EQ("http://www.example.com/?a=first%20parameter%20with%20encoded%20chars%21&b=second%20parameter%20with%20encoded%20chars%21", builder.uri().string()); } TEST(builder_test, construct_from_existing_uri) { diff --git a/test/uri_encoding_test.cpp b/test/uri_encoding_test.cpp index 726b6d45..275e5cc3 100644 --- a/test/uri_encoding_test.cpp +++ b/test/uri_encoding_test.cpp @@ -54,7 +54,7 @@ TEST(uri_encoding_test, encode_query_iterator) { std::string instance; network::uri::encode_query(std::begin(unencoded), std::end(unencoded), std::back_inserter(instance)); - ASSERT_EQ("!%23$&'()*+,/:;=?@%5B%5D", instance); + ASSERT_EQ("%21%23%24%26%27%28%29%2A%2B%2C/%3A;=%3F@%5B%5D", instance); } TEST(uri_encoding_test, encode_fragment_iterator) { From a1f53aed1173d513daafcac8104e0ea0563d1d11 Mon Sep 17 00:00:00 2001 From: Martin Trenkmann Date: Thu, 18 Oct 2018 17:49:23 +0200 Subject: [PATCH 17/19] Remove obsolete code --- include/network/uri/detail/encode.hpp | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/include/network/uri/detail/encode.hpp b/include/network/uri/detail/encode.hpp index 6dd50250..7d308dff 100644 --- a/include/network/uri/detail/encode.hpp +++ b/include/network/uri/detail/encode.hpp @@ -47,25 +47,6 @@ bool is_unreserved(charT in) { (in == '~'); } -template -bool is_sub_delim(charT in) { - switch (in) { - case '!': - case '$': - case '&': - case '\'': - case '(': - case ')': - case '*': - case '+': - case ',': - case ';': - case '=': - return true; - } - return false; -} - template void encode_char(charT in, OutputIterator &out, const char *ignore = "") { if (is_unreserved(in)) { From 6e3e36c2b4b45eb42ed883da38521f012019ad7e Mon Sep 17 00:00:00 2001 From: Martin Trenkmann Date: Thu, 18 Oct 2018 19:12:47 +0200 Subject: [PATCH 18/19] Do not encode slash and qmark in query component encoding --- include/network/uri/detail/encode.hpp | 2 +- test/uri_builder_test.cpp | 20 ++++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/include/network/uri/detail/encode.hpp b/include/network/uri/detail/encode.hpp index 7d308dff..333e1f2e 100644 --- a/include/network/uri/detail/encode.hpp +++ b/include/network/uri/detail/encode.hpp @@ -121,7 +121,7 @@ OutputIterator encode_query_component(InputIterator first, InputIterator last, OutputIterator out) { auto it = first; while (it != last) { - detail::encode_char(*it, out); + detail::encode_char(*it, out, "/?"); ++it; } return out; diff --git a/test/uri_builder_test.cpp b/test/uri_builder_test.cpp index 68ed0107..62487b45 100644 --- a/test/uri_builder_test.cpp +++ b/test/uri_builder_test.cpp @@ -805,12 +805,6 @@ TEST(builder_test, append_query_key_value_pair_encodes_equals_sign) { ASSERT_EQ(network::string_view("%3D"), ub.uri().query_begin()->second); } -TEST(builder_test, append_query_key_value_pair_encodes_question_mark) { - network::uri_builder ub(network::uri("http://example.com")); - ASSERT_NO_THROW(ub.append_query_key_value_pair("q", "?")); - ASSERT_EQ(network::string_view("%3F"), ub.uri().query_begin()->second); -} - TEST(builder_test, append_query_key_value_pair_encodes_number_sign) { network::uri_builder ub(network::uri("http://example.com")); ASSERT_NO_THROW(ub.append_query_key_value_pair("q", "#")); @@ -828,3 +822,17 @@ TEST(builder_test, append_query_key_value_pair_encodes_ampersand) { ASSERT_NO_THROW(ub.append_query_key_value_pair("q", "&")); ASSERT_EQ(network::string_view("%26"), ub.uri().query_begin()->second); } + +TEST(builder_test, append_query_key_value_pair_does_not_encode_slash) { + // https://tools.ietf.org/html/rfc3986#section-3.4 + network::uri_builder ub(network::uri("http://example.com")); + ASSERT_NO_THROW(ub.append_query_key_value_pair("q", "/")); + ASSERT_EQ(network::string_view("/"), ub.uri().query_begin()->second); +} + +TEST(builder_test, append_query_key_value_pair_does_not_encode_qmark) { + // https://tools.ietf.org/html/rfc3986#section-3.4 + network::uri_builder ub(network::uri("http://example.com")); + ASSERT_NO_THROW(ub.append_query_key_value_pair("q", "?")); + ASSERT_EQ(network::string_view("?"), ub.uri().query_begin()->second); +} From 15fb36efefd1c6b7bb980903be525ded77f6e024 Mon Sep 17 00:00:00 2001 From: Martin Trenkmann Date: Thu, 18 Oct 2018 20:06:28 +0200 Subject: [PATCH 19/19] Roll back --- include/network/uri/detail/encode.hpp | 2 +- test/uri_encoding_test.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/network/uri/detail/encode.hpp b/include/network/uri/detail/encode.hpp index 333e1f2e..e710d963 100644 --- a/include/network/uri/detail/encode.hpp +++ b/include/network/uri/detail/encode.hpp @@ -110,7 +110,7 @@ OutputIterator encode_query(InputIterator first, InputIterator last, OutputIterator out) { auto it = first; while (it != last) { - detail::encode_char(*it, out, "/.@%;="); + detail::encode_char(*it, out, "/.@&%;="); ++it; } return out; diff --git a/test/uri_encoding_test.cpp b/test/uri_encoding_test.cpp index 275e5cc3..6a73cda3 100644 --- a/test/uri_encoding_test.cpp +++ b/test/uri_encoding_test.cpp @@ -54,7 +54,7 @@ TEST(uri_encoding_test, encode_query_iterator) { std::string instance; network::uri::encode_query(std::begin(unencoded), std::end(unencoded), std::back_inserter(instance)); - ASSERT_EQ("%21%23%24%26%27%28%29%2A%2B%2C/%3A;=%3F@%5B%5D", instance); + ASSERT_EQ("%21%23%24&%27%28%29%2A%2B%2C/%3A;=%3F@%5B%5D", instance); } TEST(uri_encoding_test, encode_fragment_iterator) {