Line | Branch | Exec | Source |
---|---|---|---|
1 | // | ||
2 | // Copyright (c) 2019 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 | #ifndef BOOST_URL_DETAIL_IMPL_DECODE_IPP | ||
11 | #define BOOST_URL_DETAIL_IMPL_DECODE_IPP | ||
12 | |||
13 | #include <boost/url/detail/config.hpp> | ||
14 | #include <boost/url/detail/decode.hpp> | ||
15 | #include <boost/url/grammar/charset.hpp> | ||
16 | #include <boost/url/grammar/hexdig_chars.hpp> | ||
17 | #include <memory> | ||
18 | |||
19 | namespace boost { | ||
20 | namespace urls { | ||
21 | namespace detail { | ||
22 | |||
23 | char | ||
24 | 773 | decode_one( | |
25 | char const* const it) noexcept | ||
26 | { | ||
27 | 773 | auto d0 = grammar::hexdig_value(it[0]); | |
28 | 773 | auto d1 = grammar::hexdig_value(it[1]); | |
29 | return static_cast<char>( | ||
30 | 773 | ((static_cast< | |
31 | 773 | unsigned char>(d0) << 4) + | |
32 | 773 | (static_cast< | |
33 | 773 | unsigned char>(d1)))); | |
34 | } | ||
35 | |||
36 | std::size_t | ||
37 | 1817 | decode_bytes_unsafe( | |
38 | core::string_view s) noexcept | ||
39 | { | ||
40 | 1817 | auto p = s.begin(); | |
41 | 1817 | auto const end = s.end(); | |
42 | 1817 | std::size_t dn = 0; | |
43 |
2/2✓ Branch 1 taken 795 times.
✓ Branch 2 taken 1022 times.
|
1817 | if(s.size() >= 3) |
44 | { | ||
45 | 795 | auto const safe_end = end - 2; | |
46 |
2/2✓ Branch 0 taken 6265 times.
✓ Branch 1 taken 795 times.
|
7060 | while(p < safe_end) |
47 | { | ||
48 |
2/2✓ Branch 0 taken 6006 times.
✓ Branch 1 taken 259 times.
|
6265 | if(*p != '%') |
49 | 6006 | p += 1; | |
50 | else | ||
51 | 259 | p += 3; | |
52 | 6265 | ++dn; | |
53 | } | ||
54 | } | ||
55 | 1817 | dn += end - p; | |
56 | 1817 | return dn; | |
57 | } | ||
58 | |||
59 | std::size_t | ||
60 | 2691 | decode_unsafe( | |
61 | char* const dest0, | ||
62 | char const* end, | ||
63 | core::string_view s, | ||
64 | encoding_opts opt) noexcept | ||
65 | { | ||
66 | 2691 | auto it = s.data(); | |
67 | 2691 | auto const last = it + s.size(); | |
68 | 2691 | auto dest = dest0; | |
69 | |||
70 |
2/2✓ Branch 0 taken 709 times.
✓ Branch 1 taken 1982 times.
|
2691 | if(opt.space_as_plus) |
71 | { | ||
72 |
2/2✓ Branch 0 taken 4247 times.
✓ Branch 1 taken 709 times.
|
4956 | while(it != last) |
73 | { | ||
74 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4247 times.
|
4247 | if(dest == end) |
75 | { | ||
76 | // dest too small | ||
77 | ✗ | return dest - dest0; | |
78 | } | ||
79 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4242 times.
|
4247 | if(*it == '+') |
80 | { | ||
81 | // plus to space | ||
82 | 5 | *dest++ = ' '; | |
83 | 5 | ++it; | |
84 | 5 | continue; | |
85 | } | ||
86 |
2/2✓ Branch 0 taken 105 times.
✓ Branch 1 taken 4137 times.
|
4242 | if(*it == '%') |
87 | { | ||
88 | // escaped | ||
89 | 105 | ++it; | |
90 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 105 times.
|
105 | if(last - it < 2) |
91 | { | ||
92 | // missing input, | ||
93 | // initialize output | ||
94 | ✗ | std::memset(dest, | |
95 | ✗ | 0, end - dest); | |
96 | ✗ | return dest - dest0; | |
97 | } | ||
98 | 105 | *dest++ = decode_one(it); | |
99 | 105 | it += 2; | |
100 | 105 | continue; | |
101 | } | ||
102 | // unescaped | ||
103 | 4137 | *dest++ = *it++; | |
104 | } | ||
105 | 709 | return dest - dest0; | |
106 | } | ||
107 | |||
108 |
2/2✓ Branch 0 taken 10628 times.
✓ Branch 1 taken 1982 times.
|
12610 | while(it != last) |
109 | { | ||
110 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10628 times.
|
10628 | if(dest == end) |
111 | { | ||
112 | // dest too small | ||
113 | ✗ | return dest - dest0; | |
114 | } | ||
115 |
2/2✓ Branch 0 taken 561 times.
✓ Branch 1 taken 10067 times.
|
10628 | if(*it == '%') |
116 | { | ||
117 | // escaped | ||
118 | 561 | ++it; | |
119 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 561 times.
|
561 | if(last - it < 2) |
120 | { | ||
121 | // missing input, | ||
122 | // initialize output | ||
123 | ✗ | std::memset(dest, | |
124 | ✗ | 0, end - dest); | |
125 | ✗ | return dest - dest0; | |
126 | } | ||
127 | 561 | *dest++ = decode_one(it); | |
128 | 561 | it += 2; | |
129 | 561 | continue; | |
130 | } | ||
131 | // unescaped | ||
132 | 10067 | *dest++ = *it++; | |
133 | } | ||
134 | 1982 | return dest - dest0; | |
135 | } | ||
136 | |||
137 | } // detail | ||
138 | } // urls | ||
139 | } // boost | ||
140 | |||
141 | #endif | ||
142 |