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