diff --git a/src/v1/core/url_parser_context.cpp b/src/v1/core/url_parser_context.cpp index 7fbe8899..997ffa0a 100644 --- a/src/v1/core/url_parser_context.cpp +++ b/src/v1/core/url_parser_context.cpp @@ -75,11 +75,13 @@ inline auto is_windows_drive_letter(std::string_view segment) noexcept { } inline auto is_single_dot_path_segment(std::string_view segment) noexcept { - return (segment == ".") || (segment == "%2E"); + return (segment == ".") || (segment == "%2e") || (segment == "%2E"); } auto is_double_dot_path_segment(std::string_view segment) noexcept { - return (segment == "..") || (segment == "%2E.") || (segment == ".%2E") || (segment == "%2E%2E"); + return (segment == "..") || (segment == "%2e.") || (segment == ".%2e") || (segment == "%2e%2e") || + (segment == "%2E.") || (segment == ".%2E") || (segment == "%2E%2E") || (segment == "%2E%2e") || + (segment == "%%2E"); } void shorten_path(std::string_view scheme, std::vector &path) { diff --git a/src/v1/domain/domain.cpp b/src/v1/domain/domain.cpp index 1b271182..4fe5d5ab 100644 --- a/src/v1/domain/domain.cpp +++ b/src/v1/domain/domain.cpp @@ -19,13 +19,6 @@ #include "idna_code_point_map_iterator.hpp" #include "punycode.hpp" -#if !defined(SKYR_DOMAIN_MAX_DOMAIN_LENGTH) -#define SKYR_DOMAIN_MAX_DOMAIN_LENGTH 253 -#endif // !defined(SKYR_DOMAIN_MAX_DOMAIN_LENGTH) - -#if !defined(SKYR_DOMAIN_MAX_LABEL_LENGTH) -#define SKYR_DOMAIN_MAX_LABEL_LENGTH 63 -#endif // !defined(SKYR_LABEL_MAX_DOMAIN_LENGTH) /// How many labels can be in a domain? /// https://www.farsightsecurity.com/blog/txt-record/rrlabel-20171013/ @@ -41,7 +34,7 @@ auto map_code_points( U32Range &&domain_name, bool use_std3_ascii_rules, bool transitional_processing, - static_vector *result) + std::u32string *result) -> tl::expected { auto range = views::map_code_points(domain_name, use_std3_ascii_rules, transitional_processing); auto first = std::cbegin(range); @@ -50,7 +43,7 @@ auto map_code_points( if (!*it) { return tl::make_unexpected((*it).error()); } - result->emplace_back((*it).value()); + result->push_back((*it).value()); if (result->size() == result->max_size()) { return tl::make_unexpected(domain_errc::invalid_length); } @@ -113,7 +106,7 @@ auto domain_to_ascii( using namespace std::string_view_literals; auto u32domain_name = unicode::views::as_u8(domain_name) | unicode::transforms::to_u32; - auto mapped_domain_name = static_vector{}; + auto mapped_domain_name = std::u32string{}; auto result = map_code_points(u32domain_name, use_std3_ascii_rules, transitional_processing, &mapped_domain_name); if (!result) { return tl::make_unexpected(result.error()); @@ -123,8 +116,7 @@ auto domain_to_ascii( return std::u32string_view(std::addressof(*std::begin(label)), ranges::distance(label)); }; - /// TODO: try this without allocating strings (e.g. for large strings that don't use SBO) - auto labels = static_vector, SKYR_DOMAIN_MAX_NUM_LABELS>{}; + auto labels = static_vector{}; for (auto &&label : mapped_domain_name | ranges::views::split(U'.') | ranges::views::transform(to_string_view)) { if (labels.size() == labels.max_size()) { return tl::make_unexpected(domain_errc::too_many_labels); @@ -174,15 +166,18 @@ auto domain_to_ascii( labels.emplace_back(); } + constexpr auto max_domain_length = 253; + constexpr auto max_label_length = 63; + if (verify_dns_length) { auto length = mapped_domain_name.size(); - if ((length < 1) || (length > 253)) { + if ((length < 1) || (length > max_domain_length)) { return tl::make_unexpected(domain_errc::invalid_length); } for (const auto &label : labels) { auto label_length = label.size(); - if ((label_length < 1) || (label_length > 63)) { + if ((label_length < 1) || (label_length > max_label_length)) { return tl::make_unexpected(domain_errc::invalid_length); } } @@ -213,7 +208,7 @@ auto domain_to_u8(std::string_view domain_name, [[maybe_unused]] bool *validatio return std::string_view(std::addressof(*std::begin(label)), ranges::distance(label)); }; - auto labels = static_vector, SKYR_DOMAIN_MAX_NUM_LABELS>{}; + auto labels = static_vector{}; for (auto &&label : domain_name | ranges::views::split('.') | ranges::views::transform(to_string_view)) { if (labels.size() == labels.max_size()) { return tl::make_unexpected(domain_errc::too_many_labels); diff --git a/tests/allocations/host_parsing_tests.cpp b/tests/allocations/host_parsing_tests.cpp index 3f1b763f..31149372 100644 --- a/tests/allocations/host_parsing_tests.cpp +++ b/tests/allocations/host_parsing_tests.cpp @@ -18,7 +18,8 @@ int main() { "[2001:0db8:0:0::1428:57ab]"sv, "localhost"sv, "a.b.c.d.e.f.g.h.i.j.k.l.example.com"sv, - "sub.llanfairpwllgwyngyllgogerychwndrwbwllllantysiliogogogoch.com"sv + "sub.llanfairpwllgwyngyllgogerychwndrwbwllllantysiliogogogoch.com"sv, + "i am a terrible host name and n\0t in any way.valid.but. i am useful to validate @llocation"sv }; for (auto &&host_string : host_strings) {