GCC Code Coverage Report


Directory: ./
File: libs/http/src/server/detail/pct_decode.cpp
Date: 2026-01-20 00:11:35
Exec Total Coverage
Lines: 57 60 95.0%
Functions: 3 3 100.0%
Branches: 27 29 93.1%

Line Branch Exec Source
1 //
2 // Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot 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/cppalliance/http
8 //
9
10 #include "src/server/detail/pct_decode.hpp"
11
12 namespace boost {
13 namespace http {
14 namespace detail {
15
16 bool
17 37 ci_is_equal(
18 core::string_view s0,
19 core::string_view s1) noexcept
20 {
21 37 auto n = s0.size();
22
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 37 times.
37 if(s1.size() != n)
23 return false;
24 37 auto p1 = s0.data();
25 37 auto p2 = s1.data();
26 char a, b;
27 // fast loop
28
2/2
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 29 times.
155 while(n--)
29 {
30 126 a = *p1++;
31 126 b = *p2++;
32
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 118 times.
126 if(a != b)
33 8 goto slow;
34 }
35 29 return true;
36 do
37 {
38 5 a = *p1++;
39 5 b = *p2++;
40 13 slow:
41
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 8 times.
26 if( grammar::to_lower(a) !=
42 13 grammar::to_lower(b))
43 5 return false;
44 }
45
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 3 times.
8 while(n--);
46 3 return true;
47 }
48
49 std::string
50 116 pct_decode(
51 urls::pct_string_view s)
52 {
53 116 std::string result;
54 116 core::string_view sv(s);
55
1/1
✓ Branch 2 taken 116 times.
116 result.reserve(s.size());
56 116 auto it = sv.data();
57 116 auto const end = it + sv.size();
58 for(;;)
59 {
60
2/2
✓ Branch 0 taken 116 times.
✓ Branch 1 taken 261 times.
377 if(it == end)
61 116 break;
62
2/2
✓ Branch 0 taken 260 times.
✓ Branch 1 taken 1 times.
261 if(*it != '%')
63 {
64
1/1
✓ Branch 1 taken 260 times.
260 result.push_back(*it++);
65 260 continue;
66 }
67 1 ++it;
68 #if 0
69 // pct_string_view can never have invalid pct-encodings
70 if(it == end)
71 goto invalid;
72 #endif
73 1 auto d0 = urls::grammar::hexdig_value(*it++);
74 #if 0
75 // pct_string_view can never have invalid pct-encodings
76 if( d0 < 0 ||
77 it == end)
78 goto invalid;
79 #endif
80 1 auto d1 = urls::grammar::hexdig_value(*it++);
81 #if 0
82 // pct_string_view can never have invalid pct-encodings
83 if(d1 < 0)
84 goto invalid;
85 #endif
86
1/1
✓ Branch 1 taken 1 times.
1 result.push_back(d0 * 16 + d1);
87 261 }
88 232 return result;
89 #if 0
90 invalid:
91 // can't get here, as received a pct_string_view
92 detail::throw_invalid_argument();
93 #endif
94 }
95
96 // decode all percent escapes except slashes '/' and '\'
97 std::string
98 58 pct_decode_path(
99 urls::pct_string_view s)
100 {
101 58 std::string result;
102 58 core::string_view sv(s);
103
1/1
✓ Branch 2 taken 58 times.
58 result.reserve(s.size());
104 58 auto it = sv.data();
105 58 auto const end = it + sv.size();
106 for(;;)
107 {
108
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 169 times.
227 if(it == end)
109 58 break;
110
2/2
✓ Branch 0 taken 167 times.
✓ Branch 1 taken 2 times.
169 if(*it != '%')
111 {
112
1/1
✓ Branch 1 taken 167 times.
167 result.push_back(*it++);
113 167 continue;
114 }
115 2 ++it;
116 #if 0
117 // pct_string_view can never have invalid pct-encodings
118 if(it == end)
119 goto invalid;
120 #endif
121 2 auto d0 = urls::grammar::hexdig_value(*it++);
122 #if 0
123 // pct_string_view can never have invalid pct-encodings
124 if( d0 < 0 ||
125 it == end)
126 goto invalid;
127 #endif
128 2 auto d1 = urls::grammar::hexdig_value(*it++);
129 #if 0
130 // pct_string_view can never have invalid pct-encodings
131 if(d1 < 0)
132 goto invalid;
133 #endif
134 2 char c = d0 * 16 + d1;
135
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 if( c != '/' &&
136 c != '\\')
137 {
138
1/1
✓ Branch 1 taken 1 times.
1 result.push_back(c);
139 1 continue;
140 }
141
1/1
✓ Branch 1 taken 1 times.
1 result.append(it - 3, 3);
142 169 }
143 116 return result;
144 #if 0
145 invalid:
146 // can't get here, as received a pct_string_view
147 detail::throw_invalid_argument();
148 #endif
149 }
150
151 } // detail
152 } // http
153 } // boost
154