diff --git a/include/upa/url.h b/include/upa/url.h index a36f076..6a08ddf 100644 --- a/include/upa/url.h +++ b/include/upa/url.h @@ -1952,19 +1952,24 @@ inline validation_errc url_parser::url_parse(url_serializer& urls, const CharT* if (is_end_of_authority || state_override) { if (pointer < end_of_digits) { - // is port + // url string contains port + // skip the leading zeros except the last + pointer = std::find_if(pointer, end_of_digits - 1, [](CharT c) { return c != '0'; }); + // check port <= 65535 (0xFFFF) + if (std::distance(pointer, end_of_digits) > 5) + return validation_errc::port_out_of_range; + // port length <= 5 int port = 0; - for (auto it = pointer; it < end_of_digits; ++it) { + for (auto it = pointer; it < end_of_digits; ++it) port = port * 10 + (*it - '0'); - // 2.1.2. If port is greater than 2^16 − 1, port-out-of-range - // validation error, return failure - if (port > 0xFFFF) - return validation_errc::port_out_of_range; - } + // 2.1.2. If port is greater than 2^16 − 1, port-out-of-range + // validation error, return failure + if (port > 0xFFFF) + return validation_errc::port_out_of_range; if (urls.need_save()) { // set port if not default if (urls.scheme_inf() == nullptr || urls.scheme_inf()->default_port != port) { - util::unsigned_to_str(port, urls.start_part(url::PORT), 10); + util::append(urls.start_part(url::PORT), str_arg{ pointer, end_of_digits }); urls.save_part(); urls.set_flag(url::PORT_FLAG); } else { diff --git a/include/upa/util.h b/include/upa/util.h index 6871795..522eec8 100644 --- a/include/upa/util.h +++ b/include/upa/util.h @@ -104,16 +104,28 @@ inline std::size_t add_sizes(std::size_t size1, std::size_t size2, std::size_t m return size1 + size2; } -template -inline void append(std::string& dest, const StrT& src) { #ifdef _MSC_VER +// the value_type of dest and src are the same (char) +template ::value, int>::type = 0> +inline void append(std::string& dest, const StrT& src) { + dest.append(src.begin(), src.end()); +} + +// the value_type of dest and src are different +template ::value, int>::type = 0> +inline void append(std::string& dest, const StrT& src) { dest.reserve(add_sizes(dest.size(), src.size(), dest.max_size())); for (const auto c : src) dest.push_back(static_cast(c)); +} #else +template +inline void append(std::string& dest, const StrT& src) { dest.append(src.begin(), src.end()); -#endif } +#endif template inline void append_tr(std::string& dest, const CharT* first, const CharT* last, UnaryOperation unary_op) {