GCC Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 95.2% 59 / 12 / 74
Functions: 100.0% 7 / 0 / 7
Branches: 95.0% 19 / 8 / 28

libs/url/src/detail/decode.cpp
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 <boost/url/detail/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 908 decode_one(
23 char const* const it) noexcept
24 {
25 908 auto d0 = grammar::hexdig_value(it[0]);
26 908 auto d1 = grammar::hexdig_value(it[1]);
27 return static_cast<char>(
28 908 ((static_cast<
29 908 unsigned char>(d0) << 4) +
30 908 (static_cast<
31 908 unsigned char>(d1))));
32 }
33
34 std::size_t
35 2227 decode_bytes_unsafe(
36 core::string_view s) noexcept
37 {
38 2227 auto p = s.begin();
39 2227 auto const end = s.end();
40 2227 std::size_t dn = 0;
41
2/2
✓ Branch 1 taken 1034 times.
✓ Branch 2 taken 1193 times.
2227 if(s.size() >= 3)
42 {
43 1034 auto const safe_end = end - 2;
44
2/2
✓ Branch 0 taken 7394 times.
✓ Branch 1 taken 1034 times.
8428 while(p < safe_end)
45 {
46
2/2
✓ Branch 0 taken 7126 times.
✓ Branch 1 taken 268 times.
7394 if(*p != '%')
47 7126 p += 1;
48 else
49 268 p += 3;
50 7394 ++dn;
51 }
52 }
53 2227 dn += end - p;
54 2227 return dn;
55 }
56
57 template <bool SpaceAsPlus>
58 std::size_t
59 decode_unsafe_is_plus_impl(char c);
60
61 template <>
62 std::size_t
63 7920 decode_unsafe_is_plus_impl<true>(char c)
64 {
65 7920 return c == '+';
66 }
67
68 template <>
69 std::size_t
70 9003 decode_unsafe_is_plus_impl<false>(char)
71 {
72 9003 return false;
73 }
74
75
76 template <bool SpaceAsPlus>
77 std::size_t
78 2991 decode_unsafe_impl(
79 char* const dest0,
80 char const* end,
81 core::string_view s) noexcept
82 {
83 2991 auto it = s.data();
84 2991 auto const last = it + s.size();
85 2991 auto dest = dest0;
86
87
4/4
unsigned long boost::urls::detail::decode_unsafe_impl<false>(char*, char const*, boost::core::basic_string_view<char>):
✓ Branch 0 taken 9004 times.
✓ Branch 1 taken 1692 times.
unsigned long boost::urls::detail::decode_unsafe_impl<true>(char*, char const*, boost::core::basic_string_view<char>):
✓ Branch 0 taken 7920 times.
✓ Branch 1 taken 1298 times.
19914 while(it != last)
88 {
89 // LCOV_EXCL_START
90 if(dest == end)
91 {
92 /*
93 * dest too small: unreachable
94 * public functions always pass
95 * a buffer of sufficient size
96 */
97 return dest - dest0;
98 }
99 // LCOV_EXCL_STOP
100
3/4
unsigned long boost::urls::detail::decode_unsafe_impl<false>(char*, char const*, boost::core::basic_string_view<char>):
✗ Branch 1 not taken.
✓ Branch 2 taken 9003 times.
unsigned long boost::urls::detail::decode_unsafe_impl<true>(char*, char const*, boost::core::basic_string_view<char>):
✓ Branch 1 taken 46 times.
✓ Branch 2 taken 7874 times.
16923 if(decode_unsafe_is_plus_impl<SpaceAsPlus>(*it))
101 {
102 // plus to space
103 46 *dest++ = ' ';
104 46 ++it;
105 46 continue;
106 }
107
4/4
unsigned long boost::urls::detail::decode_unsafe_impl<false>(char*, char const*, boost::core::basic_string_view<char>):
✓ Branch 0 taken 628 times.
✓ Branch 1 taken 8375 times.
unsigned long boost::urls::detail::decode_unsafe_impl<true>(char*, char const*, boost::core::basic_string_view<char>):
✓ Branch 0 taken 151 times.
✓ Branch 1 taken 7723 times.
16877 if(*it == '%')
108 {
109 // escaped
110 779 ++it;
111 // LCOV_EXCL_START
112 if(last - it < 2)
113 {
114 // `%` not followed by two hex digits
115 // invalid input: unreachable
116 // public functions always pass
117 // a valid string_view.
118 // initialize output
119 std::memset(dest,
120 0, end - dest);
121 return dest - dest0;
122 }
123 // LCOV_EXCL_STOP
124 779 *dest++ = decode_one(it);
125 779 it += 2;
126 779 continue;
127 }
128 // unescaped
129 16098 *dest++ = *it++;
130 }
131 2990 return dest - dest0;
132 }
133
134 std::size_t
135 2991 decode_unsafe(
136 char* const dest0,
137 char const* end,
138 core::string_view s,
139 encoding_opts opt) noexcept
140 {
141
2/2
✓ Branch 0 taken 1298 times.
✓ Branch 1 taken 1693 times.
2991 if(opt.space_as_plus)
142 {
143 1298 return decode_unsafe_impl<true>(
144 1298 dest0, end, s);
145 }
146 1693 return decode_unsafe_impl<false>(
147 1693 dest0, end, s);
148 }
149
150 } // detail
151 } // urls
152 } // boost
153