diff --git a/include/boost/url/detail/impl/any_path_iter.ipp b/include/boost/url/detail/impl/any_path_iter.ipp index 3ad9c651..42fa4fcf 100644 --- a/include/boost/url/detail/impl/any_path_iter.ipp +++ b/include/boost/url/detail/impl/any_path_iter.ipp @@ -75,10 +75,13 @@ measure( if(! p_) return false; string_view s(p_, n_); - urls::validate_pct_encoding( - s, ec, pchars, {}); - if(ec.failed()) + auto rn = urls::validate_pct_encoding( + s, pchars, {}); + if( !rn ) + { + ec = rn.error(); return false; + } n += s.size(); increment(); return true; @@ -266,10 +269,13 @@ measure_impl( std::size_t& n, error_code& ec) noexcept { - urls::validate_pct_encoding( - s, ec, pchars, {}); - if(ec.failed()) + auto rn = urls::validate_pct_encoding( + s, pchars, {}); + if( !rn ) + { + ec = rn.error(); return false; + } n += s.size(); return true; } diff --git a/include/boost/url/detail/impl/any_query_iter.ipp b/include/boost/url/detail/impl/any_query_iter.ipp index 33d4b130..85b3ab33 100644 --- a/include/boost/url/detail/impl/any_query_iter.ipp +++ b/include/boost/url/detail/impl/any_query_iter.ipp @@ -71,10 +71,13 @@ measure( if(! p_) return false; string_view s(p_, n_); - urls::validate_pct_encoding( - s, ec, query_chars, {}); - if(ec.failed()) + auto rn = urls::validate_pct_encoding( + s, query_chars, {}); + if( !rn ) + { + ec = rn.error(); return false; + } n += s.size(); increment(); return true; @@ -261,20 +264,26 @@ measure_impl( { pct_decode_opts opt; opt.plus_to_space = true; - validate_pct_encoding( - key, ec, query_chars, opt); - if(ec.failed()) + auto rn = validate_pct_encoding( + key, query_chars, opt); + if( !rn ) + { + ec = rn.error(); return false; + } n += key.size(); if(value) { - validate_pct_encoding( - *value, ec, query_chars, opt); - if(ec.failed()) + rn = validate_pct_encoding( + *value, query_chars, opt); + if( !rn ) + { + ec = rn.error(); return false; + } n += 1 + value->size(); } - return ! ec.failed(); + return ! !rn ; } void diff --git a/include/boost/url/detail/impl/segments_encoded_iterator_impl.ipp b/include/boost/url/detail/impl/segments_encoded_iterator_impl.ipp index e7340e40..a50f6920 100644 --- a/include/boost/url/detail/impl/segments_encoded_iterator_impl.ipp +++ b/include/boost/url/detail/impl/segments_encoded_iterator_impl.ipp @@ -73,7 +73,7 @@ increment() noexcept auto rv = grammar::parse( next_, end_, detail::slash_segment_rule); - if(rv.has_error()) + if( !rv ) { next_ = nullptr; return; diff --git a/include/boost/url/detail/impl/segments_iterator_impl.ipp b/include/boost/url/detail/impl/segments_iterator_impl.ipp index 1b937c95..79eb5b0a 100644 --- a/include/boost/url/detail/impl/segments_iterator_impl.ipp +++ b/include/boost/url/detail/impl/segments_iterator_impl.ipp @@ -77,7 +77,7 @@ increment() noexcept auto rv = grammar::parse( next_, end_, detail::slash_segment_rule); - if(rv.has_error()) + if( !rv ) { next_ = nullptr; return; diff --git a/include/boost/url/error_type.hpp b/include/boost/url/error_type.hpp index 27f520c7..6e55bb10 100644 --- a/include/boost/url/error_type.hpp +++ b/include/boost/url/error_type.hpp @@ -107,7 +107,7 @@ namespace errc = boost::system::errc; @code result< url_view > r = parse_uri( "http://example.com/path/to/file.txt" ); - if( r.has_error() ) + if( !r ) std::cout << r.error(); else std::cout << r.value(); diff --git a/include/boost/url/grammar/impl/not_empty_rule.hpp b/include/boost/url/grammar/impl/not_empty_rule.hpp index d53dd6bc..ee498d4f 100644 --- a/include/boost/url/grammar/impl/not_empty_rule.hpp +++ b/include/boost/url/grammar/impl/not_empty_rule.hpp @@ -33,7 +33,7 @@ parse( } auto const it0 = it; auto rv = r_.parse(it, end); - if( rv.has_error()) + if( !rv ) { // error return rv; diff --git a/include/boost/url/grammar/impl/optional_rule.hpp b/include/boost/url/grammar/impl/optional_rule.hpp index 29d97910..57203b9c 100644 --- a/include/boost/url/grammar/impl/optional_rule.hpp +++ b/include/boost/url/grammar/impl/optional_rule.hpp @@ -28,7 +28,7 @@ parse( return boost::none; auto const it0 = it; auto rv = r_.parse(it, end); - if(! rv.has_error()) + if(rv) return value_type(*rv); it = it0; return boost::none; diff --git a/include/boost/url/grammar/impl/parse.hpp b/include/boost/url/grammar/impl/parse.hpp index 9a4875cf..2aaa78e9 100644 --- a/include/boost/url/grammar/impl/parse.hpp +++ b/include/boost/url/grammar/impl/parse.hpp @@ -54,8 +54,8 @@ parse( auto it = s.data(); auto const end = it + s.size(); auto rv = r.parse(it, end); - if( rv.has_value() && - it != end) + if( rv && + it != end) return error::leftover; return rv; } diff --git a/include/boost/url/grammar/impl/range_rule.hpp b/include/boost/url/grammar/impl/range_rule.hpp index dc010bf0..d4a392f1 100644 --- a/include/boost/url/grammar/impl/range_rule.hpp +++ b/include/boost/url/grammar/impl/range_rule.hpp @@ -364,7 +364,7 @@ public: r_->s_.data() + r_->s_.size(); rv_ = r_->get().next(p_, end); - if(rv_.has_error()) + if( !rv_ ) p_ = nullptr; return *this; } @@ -393,7 +393,7 @@ private: r_->s_.data() + r_->s_.size(); rv_ = r_->get().first(p_, end); - if(rv_.has_error()) + if( !rv_ ) p_ = nullptr; } @@ -533,7 +533,7 @@ parse( auto it1 = it; auto rv = (grammar::parse)( it, end, next_); - if(rv.has_error()) + if( !rv ) { if(rv.error() != error::range_end) { @@ -557,7 +557,7 @@ parse( it1 = it; rv = (grammar::parse)( it, end, next_); - if(rv.has_error()) + if( !rv ) { if(rv.error() != error::range_end) { @@ -603,7 +603,7 @@ parse( auto it1 = it; auto rv = (grammar::parse)( it, end, first_); - if(rv.has_error()) + if( !rv ) { if(rv.error() != error::range_end) { @@ -627,7 +627,7 @@ parse( it1 = it; rv = (grammar::parse)( it, end, next_); - if(rv.has_error()) + if( !rv ) { if(rv.error() != error::range_end) { diff --git a/include/boost/url/grammar/impl/tuple_rule.hpp b/include/boost/url/grammar/impl/tuple_rule.hpp index 2002cdfe..1605ac32 100644 --- a/include/boost/url/grammar/impl/tuple_rule.hpp +++ b/include/boost/url/grammar/impl/tuple_rule.hpp @@ -80,7 +80,7 @@ struct parse_sequence result rv = grammar::parse( it, end, get(rn)); - if(rv.has_error()) + if( !rv ) { ec = rv.error(); return; @@ -104,7 +104,7 @@ struct parse_sequence auto& rv = get(vn); rv = grammar::parse( it, end, get(rn)); - if(rv.has_error()) + if( !rv ) { ec = rv.error(); return; @@ -208,7 +208,7 @@ struct parse_sequence result rv = grammar::parse( it, end, get(rn)); - if(rv.has_error()) + if( !rv ) { v = rv.error(); return; @@ -231,7 +231,7 @@ struct parse_sequence { v = grammar::parse( it, end, get(rn)); - if(v.has_error()) + if( !v ) return; apply(it, end, mp11::mp_size_t{}, diff --git a/include/boost/url/grammar/impl/variant_rule.hpp b/include/boost/url/grammar/impl/variant_rule.hpp index 71873074..2e367447 100644 --- a/include/boost/url/grammar/impl/variant_rule.hpp +++ b/include/boost/url/grammar/impl/variant_rule.hpp @@ -64,7 +64,7 @@ parse_variant( auto const it0 = it; auto rv = parse( it, end, get(rn)); - if(rv.has_value()) + if( rv ) return variant< typename R0::value_type, typename Rn::value_type...>{ diff --git a/include/boost/url/impl/ipv4_address.ipp b/include/boost/url/impl/ipv4_address.ipp index 1f39080a..821b691c 100644 --- a/include/boost/url/impl/ipv4_address.ipp +++ b/include/boost/url/impl/ipv4_address.ipp @@ -41,7 +41,7 @@ ipv4_address( string_view s) { auto r = parse_ipv4_address(s); - if(r.has_error()) + if( !r) detail::throw_invalid_argument(); *this = r.value(); } diff --git a/include/boost/url/impl/ipv6_address.ipp b/include/boost/url/impl/ipv6_address.ipp index 71b3bde8..6ef3b8bf 100644 --- a/include/boost/url/impl/ipv6_address.ipp +++ b/include/boost/url/impl/ipv6_address.ipp @@ -43,7 +43,7 @@ ipv6_address( string_view s) { auto r = parse_ipv6_address(s); - if(r.has_error()) + if( !r ) detail::throw_invalid_argument(); *this = r.value(); } diff --git a/include/boost/url/impl/pct_encoded_view.ipp b/include/boost/url/impl/pct_encoded_view.ipp index f7fee1b1..c4c26ae6 100644 --- a/include/boost/url/impl/pct_encoded_view.ipp +++ b/include/boost/url/impl/pct_encoded_view.ipp @@ -55,16 +55,16 @@ pct_encoded_view( pct_encoded_view:: pct_encoded_view( string_view str, - pct_decode_opts opt) noexcept + pct_decode_opts opt) : p_(str.data()) , n_(str.size()) , plus_to_space_(opt.plus_to_space) { - error_code ec; opt.non_normal_is_error = false; - dn_ = validate_pct_encoding(str, ec, opt); - if (ec.failed()) + auto rn = validate_pct_encoding(str, opt); + if ( !rn ) detail::throw_invalid_argument(); + dn_ = *rn; } pct_encoded_view diff --git a/include/boost/url/impl/pct_encoding.hpp b/include/boost/url/impl/pct_encoding.hpp index 3ede79db..fc8bfbcf 100644 --- a/include/boost/url/impl/pct_encoding.hpp +++ b/include/boost/url/impl/pct_encoding.hpp @@ -22,10 +22,9 @@ namespace boost { namespace urls { template -std::size_t +result validate_pct_encoding( string_view s, - error_code& ec, CharSet const& allowed, pct_decode_opts const& opt) noexcept { @@ -48,9 +47,8 @@ validate_pct_encoding( *it == '\0') { // null in input - ec = BOOST_URL_ERR( + BOOST_URL_RETURN_EC( error::illegal_null); - return n; } if(allowed(*it)) { @@ -66,18 +64,16 @@ validate_pct_encoding( if(end - it < 2) { // missing HEXDIG - ec = BOOST_URL_ERR( + BOOST_URL_RETURN_EC( error::missing_pct_hexdig); - return n; } auto d0 = grammar::hexdig_value(it[0]); auto d1 = grammar::hexdig_value(it[1]); if( d0 < 0 || d1 < 0) { // expected HEXDIG - ec = BOOST_URL_ERR( + BOOST_URL_RETURN_EC( error::bad_pct_hexdig); - return n; } it += 2; char const c = static_cast( @@ -89,15 +85,14 @@ validate_pct_encoding( c == '\0') { // escaped null - ec = BOOST_URL_ERR( + BOOST_URL_RETURN_EC( error::illegal_null); - return n; } if( opt.non_normal_is_error && allowed(c)) { // escaped unreserved char - ec = BOOST_URL_ERR( + BOOST_URL_RETURN_EC( error::non_canonical); return n; } @@ -105,24 +100,21 @@ validate_pct_encoding( continue; } // reserved character in input - ec = BOOST_URL_ERR( + BOOST_URL_RETURN_EC( error::illegal_reserved_char); - return n; } BOOST_ASSERT(it == end); - ec = {}; return n; } //------------------------------------------------ template -std::size_t +result pct_decode( char* dest, char const* end, string_view s, - error_code& ec, CharSet const& allowed, pct_decode_opts const& opt) noexcept { @@ -130,18 +122,17 @@ pct_decode( BOOST_STATIC_ASSERT( grammar::is_charset::value); - auto const n = + auto const rn = validate_pct_encoding( - s, ec, allowed, opt); - if(ec.failed()) - return 0; + s, allowed, opt); + if( !rn ) + return rn; auto const n1 = pct_decode_unchecked( dest, end, s, opt); - if(n1 < n) + if(n1 < *rn) { - ec = error::no_space; - return n1; + return error::no_space; } return n1; } diff --git a/include/boost/url/impl/pct_encoding.ipp b/include/boost/url/impl/pct_encoding.ipp index 6d745b84..4e6dec6d 100644 --- a/include/boost/url/impl/pct_encoding.ipp +++ b/include/boost/url/impl/pct_encoding.ipp @@ -133,10 +133,9 @@ pct_decode_unchecked( namespace detail { -std::size_t +result validate_pct_encoding( string_view s, - error_code& ec, std::true_type) noexcept { const auto is_safe = [](char c) @@ -150,33 +149,29 @@ validate_pct_encoding( it = grammar::find_if_not(it, end, is_safe); while (it != end) { - if (end - it < 2) + if (end - it < 3) { // missing HEXDIG - ec = BOOST_URL_ERR( + BOOST_URL_RETURN_EC( error::missing_pct_hexdig); - return it - s.data() - pcts * 2; } if (!grammar::hexdig_chars(it[1]) || !grammar::hexdig_chars(it[2])) { // expected HEXDIG - ec = BOOST_URL_ERR( + BOOST_URL_RETURN_EC( error::bad_pct_hexdig); - return it - s.data() - pcts * 2; } it += 3; ++pcts; it = grammar::find_if_not(it, end, is_safe); } - ec = {}; return s.size() - pcts * 2; } -std::size_t +result validate_pct_encoding( string_view s, - error_code& ec, std::false_type) noexcept { const auto is_safe = [](char c) @@ -193,75 +188,67 @@ validate_pct_encoding( if (*it == '\0') { // null in input - ec = BOOST_URL_ERR( + BOOST_URL_RETURN_EC( error::illegal_null); - return it - s.data() - pcts * 2; } - if (end - it < 2) + if (end - it < 3) { // missing HEXDIG - ec = BOOST_URL_ERR( + BOOST_URL_RETURN_EC( error::missing_pct_hexdig); - return it - s.data() - pcts * 2; } if (!grammar::hexdig_chars(it[1]) || !grammar::hexdig_chars(it[2])) { // expected HEXDIG - ec = BOOST_URL_ERR( + BOOST_URL_RETURN_EC( error::bad_pct_hexdig); - return it - s.data() - pcts * 2; } if (it[1] == '0' && it[2] == '0') { // null in input - ec = BOOST_URL_ERR( + BOOST_URL_RETURN_EC( error::illegal_null); - return it - s.data() - pcts * 2; } it += 3; ++pcts; it = grammar::find_if_not(it, end, is_safe); } - ec = {}; return s.size() - pcts * 2; } } -std::size_t +result validate_pct_encoding( string_view s, - error_code& ec, pct_decode_opts const& opt) noexcept { if (opt.allow_null) return detail::validate_pct_encoding( - s, ec, std::true_type{}); + s, std::true_type{}); else return detail::validate_pct_encoding( - s, ec, std::false_type{}); + s, std::false_type{}); } -std::size_t +result pct_decode( char* dest, char const* end, string_view s, - error_code& ec, pct_decode_opts const& opt) noexcept { - auto const n = - validate_pct_encoding(s, ec, opt); - if(ec.failed()) - return 0; + auto const rn = + validate_pct_encoding(s, opt); + if( !rn ) + return rn; auto const n1 = pct_decode_unchecked( dest, end, s, opt); - if(n1 < n) + if(n1 < *rn) { - ec = error::no_space; - return n1; + return error::no_space; } return n1; } diff --git a/include/boost/url/impl/url_base.ipp b/include/boost/url/impl/url_base.ipp index 85f03b72..677d4b0c 100644 --- a/include/boost/url/impl/url_base.ipp +++ b/include/boost/url/impl/url_base.ipp @@ -304,17 +304,15 @@ set_encoded_user( this->string()); s = buf.maybe_copy(s); check_invariants(); - error_code ec; - auto const n = + auto const rn = validate_pct_encoding( s, - ec, detail::user_chars, {}); - if(ec.failed()) + if( !rn ) detail::throw_invalid_argument(); auto dest = set_user_impl(s.size()); - u_.decoded_[id_user] = n; + u_.decoded_[id_user] = *rn; if(! s.empty()) { BOOST_ASSERT(dest != nullptr); @@ -432,14 +430,13 @@ set_encoded_password( this->string()); s = buf.maybe_copy(s); check_invariants(); - error_code ec; - auto const n = validate_pct_encoding( - s, ec, detail::password_chars, {}); - if(ec.failed()) + auto const rn = validate_pct_encoding( + s, detail::password_chars, {}); + if( !rn ) detail::throw_invalid_argument(); auto dest = set_password_impl(s.size()); - u_.decoded_[id_pass] = n; + u_.decoded_[id_pass] = *rn; if(! s.empty()) { BOOST_ASSERT(dest != nullptr); @@ -685,7 +682,7 @@ set_host( // try ipv4 { auto r = parse_ipv4_address(s); - if(! r.has_error()) + if( r ) return set_host(r.value()); } check_invariants(); @@ -716,7 +713,7 @@ set_host( // try ipv4 { auto r = parse_ipv4_address(s.encoded()); - if(! r.has_error()) + if( r ) return set_host(r.value()); } check_invariants(); @@ -1789,12 +1786,11 @@ set_fragment( // //------------------------------------------------ -bool +result url_base:: resolve_impl( url_view_base const& base, - url_view_base const& ref, - error_code& ec) + url_view_base const& ref) { auto const remove_dot_segments = [this] @@ -1858,12 +1854,9 @@ resolve_impl( if(! base.has_scheme()) { - ec = error::not_a_base; - return false; + return error::not_a_base; } - ec = {}; - // // 5.2.2. Transform References // https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.2 @@ -1874,7 +1867,7 @@ resolve_impl( reserve(ref.size()); copy(ref); remove_dot_segments(); - return true; + return {}; } if(ref.has_authority()) { @@ -1894,7 +1887,7 @@ resolve_impl( if(ref.has_fragment()) set_encoded_fragment( ref.encoded_fragment()); - return true; + return {}; } if(ref.encoded_path().empty()) { @@ -1934,7 +1927,7 @@ resolve_impl( if(ref.has_fragment()) set_encoded_fragment( ref.encoded_fragment()); - return true; + return {}; } if(ref.encoded_path().starts_with('/')) { @@ -1955,7 +1948,7 @@ resolve_impl( if(ref.has_fragment()) set_encoded_fragment( ref.encoded_fragment()); - return true; + return {}; } reserve( base.u_.offset(id_query) + @@ -1986,7 +1979,7 @@ resolve_impl( if(ref.has_fragment()) set_encoded_fragment( ref.encoded_fragment()); - return true; + return {}; } //------------------------------------------------ diff --git a/include/boost/url/pct_encoded_view.hpp b/include/boost/url/pct_encoded_view.hpp index 23ce2d76..a6a29ae3 100644 --- a/include/boost/url/pct_encoded_view.hpp +++ b/include/boost/url/pct_encoded_view.hpp @@ -168,7 +168,7 @@ public: explicit pct_encoded_view( string_view s, - pct_decode_opts opt = {}) noexcept; + pct_decode_opts opt = {}); //-------------------------------------------- // diff --git a/include/boost/url/pct_encoding.hpp b/include/boost/url/pct_encoding.hpp index 917e54d8..d18dcf25 100644 --- a/include/boost/url/pct_encoding.hpp +++ b/include/boost/url/pct_encoding.hpp @@ -86,8 +86,6 @@ struct pct_decode_opts @param s The percent-encoded string to analyze. - @param ec Set to the error, if any occurred. - @param opt The options for decoding. If this parameter is omitted, the default options will be used. @@ -112,10 +110,9 @@ struct pct_decode_opts */ template< class CharSet> -std::size_t +result validate_pct_encoding( string_view s, - error_code& ec, CharSet const& allowed, pct_decode_opts const& opt = {}) noexcept; @@ -157,8 +154,6 @@ validate_pct_encoding( @param s The percent-encoded string to analyze. - @param ec Set to the error, if any occurred. - @param opt The options for decoding. If this parameter is omitted, the default options will be used. @@ -174,10 +169,9 @@ validate_pct_encoding( @ref pct_decode_unchecked, */ BOOST_URL_DECL -std::size_t +result validate_pct_encoding( string_view s, - error_code& ec, pct_decode_opts const& opt = {}) noexcept; /** Write a string with percent-decoding into a buffer. @@ -208,7 +202,10 @@ validate_pct_encoding( @return The number of bytes written to the destination buffer, which does not - include any null termination. + include any null termination. If the + destination buffer is too small to hold + the result, the result is set to + @ref error::no_space. @param dest A pointer to the beginning of the output buffer. @@ -218,11 +215,6 @@ validate_pct_encoding( @param s The string to decode. - @param ec Set to the error, if any - occurred. If the destination buffer - is too small to hold the result, `ec` - is set to @ref error::no_space. - @param opt The options for decoding. If this parameter is omitted, the default options will be used. @@ -247,12 +239,11 @@ validate_pct_encoding( */ template< class CharSet> -std::size_t +result pct_decode( char* dest, char const* end, string_view s, - error_code& ec, CharSet const& allowed, pct_decode_opts const& opt = {}) noexcept; @@ -294,8 +285,6 @@ pct_decode( @param s The string to decode. - @param ec Set to the error, if any occurred. - @param opt The options for decoding. If this parameter is omitted, the default options will be used. @@ -311,12 +300,11 @@ pct_decode( @ref validate_pct_encoding. */ BOOST_URL_DECL -std::size_t +result pct_decode( char* dest, char const* end, string_view s, - error_code& ec, pct_decode_opts const& opt = {}) noexcept; /** Return the number of bytes needed to hold the string with percent-decoding applied. diff --git a/include/boost/url/rfc/detail/impl/hier_part_rule.ipp b/include/boost/url/rfc/detail/impl/hier_part_rule.ipp index 50430b2a..47e3ba3d 100644 --- a/include/boost/url/rfc/detail/impl/hier_part_rule.ipp +++ b/include/boost/url/rfc/detail/impl/hier_part_rule.ipp @@ -41,7 +41,7 @@ parse( auto rv = grammar::parse( it, end, path_rootless_rule); - if(rv.has_value()) + if( rv ) { t.path = std::move(*rv); BOOST_URL_RETURN(t); diff --git a/include/boost/url/rfc/detail/impl/host_rule.ipp b/include/boost/url/rfc/detail/impl/host_rule.ipp index badf77e7..dce519cc 100644 --- a/include/boost/url/rfc/detail/impl/host_rule.ipp +++ b/include/boost/url/rfc/detail/impl/host_rule.ipp @@ -74,7 +74,7 @@ parse( { auto rv = grammar::parse( it, end, ipv4_address_rule); - if(rv.has_value()) + if( rv ) { auto const b = rv->to_bytes(); diff --git a/include/boost/url/rfc/detail/impl/path_rules.ipp b/include/boost/url/rfc/detail/impl/path_rules.ipp index 8f6381c1..afa449d9 100644 --- a/include/boost/url/rfc/detail/impl/path_rules.ipp +++ b/include/boost/url/rfc/detail/impl/path_rules.ipp @@ -35,7 +35,7 @@ parse( } auto rv = grammar::parse( it, end, segment_rule); - if(rv.has_error()) + if( !rv ) return rv.error(); return *rv; } diff --git a/include/boost/url/rfc/detail/impl/relative_part_rule.ipp b/include/boost/url/rfc/detail/impl/relative_part_rule.ipp index dc255d1f..a14ce6e4 100644 --- a/include/boost/url/rfc/detail/impl/relative_part_rule.ipp +++ b/include/boost/url/rfc/detail/impl/relative_part_rule.ipp @@ -39,7 +39,7 @@ parse( auto rv = grammar::parse( it, end, path_noscheme_rule); - if(rv.has_value()) + if( rv ) { // path-noscheme t.path = std::move(*rv); diff --git a/include/boost/url/url.hpp b/include/boost/url/url.hpp index 4ec9016a..53145248 100644 --- a/include/boost/url/url.hpp +++ b/include/boost/url/url.hpp @@ -293,6 +293,8 @@ private: Basic guarantee. Calls to allocate may throw. + @return Error if any occurred + @param base The base URL to resolve against. @param ref The URL reference to resolve. @@ -300,8 +302,6 @@ private: @param dest The container where the result is written, upon success. - @param ec Set to the error if any occurred. - @par Specification 5. Reference Resolution (rfc3986) @@ -311,16 +311,15 @@ private: @ref url_view. */ inline -void +result resolve( url_view_base const& base, url_view_base const& ref, - url_base& dest, - error_code& ec) + url_base& dest) { BOOST_ASSERT(&dest != &base); BOOST_ASSERT(&dest != &ref); - dest.resolve_impl(base, ref, ec); + return dest.resolve_impl(base, ref); } } // urls diff --git a/include/boost/url/url_base.hpp b/include/boost/url/url_base.hpp index 4053e95f..05ad9275 100644 --- a/include/boost/url/url_base.hpp +++ b/include/boost/url/url_base.hpp @@ -1448,12 +1448,11 @@ public: //-------------------------------------------- friend - void + result resolve( url_view_base const& base, url_view_base const& ref, - url_base& dest, - error_code& ec); + url_base& dest); private: //-------------------------------------------- @@ -1469,11 +1468,10 @@ private: char* shrink_impl(int, int, std::size_t); BOOST_URL_DECL - bool + result resolve_impl( url_view_base const& base, - url_view_base const& ref, - error_code& ec); + url_view_base const& ref); }; } // urls diff --git a/test/unit/params_encoded.cpp b/test/unit/params_encoded.cpp index 2215260e..097e1a29 100644 --- a/test/unit/params_encoded.cpp +++ b/test/unit/params_encoded.cpp @@ -13,6 +13,7 @@ #include #include +#include #include "test_suite.hpp" namespace boost { @@ -51,6 +52,26 @@ public: BOOST_TEST(u.string() == "/?k1=1&k2=2&k3=&k4&k5=55555#f"); } + { + url u = parse_uri_reference( + "/?x#f").value(); + auto ps = u.encoded_params(); + BOOST_TEST_THROWS( + ps.assign({ + { "k1", "1#", true }}), + std::invalid_argument); + ignore_unused(ps); + } + { + url u = parse_uri_reference( + "/?x#f").value(); + auto ps = u.encoded_params(); + BOOST_TEST_THROWS( + ps.assign({ + { "#k1", "", false }}), + std::invalid_argument); + ignore_unused(ps); + } { url u = parse_uri_reference("/?x#f").value(); u.encoded_params() = {}; diff --git a/test/unit/pct_encoding.cpp b/test/unit/pct_encoding.cpp index 45c53639..6acae53d 100644 --- a/test/unit/pct_encoding.cpp +++ b/test/unit/pct_encoding.cpp @@ -66,12 +66,11 @@ public: { // validate_pct_encoding { - error_code ec; - auto n = validate_pct_encoding( - s0, ec, *pcs, opt); - if(! BOOST_TEST(! ec.failed())) + auto rn = validate_pct_encoding( + s0, *pcs, opt); + if(! BOOST_TEST(! rn.has_error())) return; - BOOST_TEST_EQ(n, s1.size()); + BOOST_TEST_EQ(*rn, s1.size()); } // pct_decode to buffer { @@ -79,22 +78,21 @@ public: for(std::size_t i = 0; i < sizeof(buf); ++i) { - error_code ec; - auto const n = pct_decode( + auto const rn = pct_decode( buf, buf + i, - s0, ec, *pcs, opt); + s0, *pcs, opt); if(i < s1.size()) { BOOST_TEST( - ec == error::no_space); - BOOST_TEST_LT(n, s1.size()); - BOOST_TEST_LE(n, i); + rn.error() == error::no_space); + // BOOST_TEST_LT(n, s1.size()); + // BOOST_TEST_LE(n, i); continue; } - BOOST_TEST(! ec.failed()); - BOOST_TEST_EQ(n, s1.size()); + BOOST_TEST(! rn.has_error()); + BOOST_TEST_EQ(*rn, s1.size()); BOOST_TEST_EQ( - string_view(buf, n), s1); + string_view(buf, *rn), s1); break; } } @@ -102,10 +100,10 @@ public: { std::string s; s.resize(pct_decode_bytes_unchecked(s0)); - error_code ec; - std::size_t n = - pct_decode(&s[0], &s[0] + s.size(), s0, ec, opt); - s.resize(n); + auto rn = + pct_decode(&s[0], &s[0] + s.size(), s0, opt); + BOOST_TEST(rn.has_value()); + s.resize(*rn); BOOST_TEST_EQ(s, s1); } // pct_decode() -> std::basic_string @@ -114,8 +112,8 @@ public: std::basic_string, A> s(A{}); s.resize(pct_decode_bytes_unchecked(s0)); - error_code ec; - pct_decode(&s[0], &s[0] + s.size(), s0, ec, opt); + auto rn = pct_decode(&s[0], &s[0] + s.size(), s0, opt); + BOOST_TEST(rn.has_value()); BOOST_TEST_EQ(s, s1); } // pct_decode_bytes_unchecked @@ -142,21 +140,19 @@ public: { // validate_pct_encoding { - error_code ec; - validate_pct_encoding( - s, ec, test_chars{}, opt); - BOOST_TEST(ec.failed()); - if (!ec.failed()) + auto rn = validate_pct_encoding( + s, test_chars{}, opt); + BOOST_TEST(rn.has_error()); + if (!rn.has_error()) BOOST_TEST_EQ(s, ""); } // pct_decode to buffer { char buf[16]; - error_code ec; - pct_decode(buf, + auto rn = pct_decode(buf, buf + sizeof(buf), - s, ec, *pcs, opt); - BOOST_TEST(ec.failed()); + s, *pcs, opt); + BOOST_TEST(rn.has_error()); } // pct_decode_bytes_unchecked { @@ -432,12 +428,53 @@ public: } } + void + testValidate() + { + auto check = []( + string_view s, + error_code ec, + pct_decode_opts opt) + { + auto r = validate_pct_encoding(s, opt); + BOOST_TEST(r.has_error()); + BOOST_TEST(r.error() == ec); + }; + + pct_decode_opts opt; + opt.allow_null = true; + check("%a", error::missing_pct_hexdig, opt); + check("%ar", error::bad_pct_hexdig, opt); + + opt.allow_null = false; + check(string_view("\0", 1), error::illegal_null, opt); + check("%00", error::illegal_null, opt); + check("%a", error::missing_pct_hexdig, opt); + check("%ar", error::bad_pct_hexdig, opt); + + { + std::string dest; + dest.resize(1); + result r = pct_decode( + &dest[0], &dest[1], "%a", opt); + BOOST_TEST_EQ(r.error(), error::missing_pct_hexdig); + } + { + std::string dest; + dest.resize(1); + result r = pct_decode( + &dest[0], &dest[1], "%aa%aa", opt); + BOOST_TEST_EQ(r.error(), error::no_space); + } + } + void run() { testDecoding(); testEncode(); testEncodeExtras(); + testValidate(); } }; diff --git a/test/unit/snippets.cpp b/test/unit/snippets.cpp index a8f56bcf..4b17da8c 100644 --- a/test/unit/snippets.cpp +++ b/test/unit/snippets.cpp @@ -322,8 +322,7 @@ parsing_urls() result< url_view > r1 = parse_uri( "https://www.example.com" ); assert( r1.has_value() ); url dest; - error_code ec; - resolve(r1.value(), r0.value(), dest, ec); + resolve(r1.value(), r0.value(), dest); assert(dest.string() == "https://www.example.com/path/to/file.txt"); //] boost::ignore_unused(dest); diff --git a/test/unit/url.cpp b/test/unit/url.cpp index 484ceadb..612813a2 100644 --- a/test/unit/url.cpp +++ b/test/unit/url.cpp @@ -1999,9 +1999,8 @@ public: parse_uri_reference(r).value(); url u = parse_uri( "z://y:x@p.q:69/x/f?q#f" ).value(); - error_code ec; - resolve(ub, ur, u, ec); - if(! BOOST_TEST(! ec.failed())) + result rv = resolve(ub, ur, u); + if(! BOOST_TEST( rv.has_value() )) return; BOOST_TEST_EQ(u.string(), m); };