Line data Source code
1 : //
2 : // Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com)
3 : //
4 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 : //
7 : // Official repository: https://github.com/boostorg/url
8 : //
9 :
10 :
11 : #include <boost/url/detail/config.hpp>
12 : #include <boost/url/error.hpp>
13 : #include <boost/url/pct_string_view.hpp>
14 : #include "detail/decode.hpp"
15 : #include <boost/url/grammar/hexdig_chars.hpp>
16 : #include <boost/url/detail/except.hpp>
17 :
18 : namespace boost {
19 : namespace urls {
20 :
21 : void
22 3302 : pct_string_view::
23 : decode_impl(
24 : string_token::arg& dest,
25 : encoding_opts opt) const
26 : {
27 3302 : auto p = dest.prepare(dn_);
28 3302 : if(dn_ > 0)
29 2525 : detail::decode_unsafe(
30 2525 : p, p + dn_, s_, opt);
31 3302 : }
32 :
33 : //------------------------------------------------
34 :
35 5688 : pct_string_view::
36 : pct_string_view(
37 5688 : core::string_view s)
38 : : pct_string_view(
39 5688 : make_pct_string_view(s
40 5688 : ).value(BOOST_URL_POS))
41 : {
42 5610 : }
43 :
44 : //------------------------------------------------
45 :
46 : system::result<pct_string_view>
47 5703 : make_pct_string_view(
48 : core::string_view s) noexcept
49 : {
50 5703 : auto p = s.begin();
51 5703 : auto const end = s.end();
52 5703 : std::size_t dn = 0;
53 5703 : if(s.size() >= 3)
54 : {
55 2911 : auto const safe_end = end - 2;
56 22044 : while(p < safe_end)
57 : {
58 19149 : if(*p != '%')
59 : {
60 18397 : ++p;
61 : }
62 752 : else if(
63 1499 : grammar::hexdig_value(p[1]) >= 0 &&
64 747 : grammar::hexdig_value(p[2]) >= 0)
65 : {
66 : // percent-escape
67 736 : p += 3;
68 : }
69 : else
70 : {
71 : // invalid encoding
72 16 : BOOST_URL_RETURN_EC(
73 : error::bad_pct_hexdig);
74 : }
75 19133 : ++dn;
76 : }
77 : }
78 5687 : auto const n = end - p;
79 5687 : if( (n >= 1 && p[0] == '%') ||
80 3271 : (n >= 2 && p[1] == '%'))
81 : {
82 : // invalid encoding
83 62 : BOOST_URL_RETURN_EC(
84 : error::incomplete_encoding);
85 : }
86 5625 : dn += n;
87 11250 : return make_pct_string_view_unsafe(
88 5625 : s.data(), s.size(), dn);
89 : }
90 :
91 : } // urls
92 : } // boost
93 :
94 :
|