Coverage Report

Created: 2026-09-01 13:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/root/bitcoin/src/common/url.cpp
Line
Count
Source
1
// Copyright (c) 2015-present The Bitcoin Core developers
2
// Distributed under the MIT software license, see the accompanying
3
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5
#include <common/url.h>
6
7
#include <charconv>
8
#include <cstddef>
9
#include <string>
10
#include <string_view>
11
#include <system_error>
12
13
std::string UrlDecode(std::string_view url_encoded)
14
882
{
15
882
    std::string res;
16
882
    res.reserve(url_encoded.size());
17
18
8.52k
    for (size_t i = 0; i < url_encoded.size(); ++i) {
  Branch (18:24): [True: 7.64k, False: 882]
19
7.64k
        char c = url_encoded[i];
20
        // Special handling for percent which should be followed by two hex digits
21
        // representing an octet values, see RFC 3986, Section 2.1 Percent-Encoding
22
7.64k
        if (c == '%' && i + 2 < url_encoded.size()) {
  Branch (22:13): [True: 271, False: 7.36k]
  Branch (22:25): [True: 259, False: 12]
23
259
            unsigned int decoded_value{0};
24
259
            auto [p, ec] = std::from_chars(url_encoded.data() + i + 1, url_encoded.data() + i + 3, decoded_value, 16);
25
26
            // Only if there is no error and the pointer is set to the end of
27
            // the string, we can be sure both characters were valid hex
28
259
            if (ec == std::errc{} && p == url_encoded.data() + i + 3) {
  Branch (28:17): [True: 163, False: 96]
  Branch (28:38): [True: 104, False: 59]
29
104
                res += static_cast<char>(decoded_value);
30
                // Next two characters are part of the percent encoding
31
104
                i += 2;
32
104
                continue;
33
104
            }
34
            // In case of invalid percent encoding, add the '%' and continue
35
259
        }
36
7.53k
        res += c;
37
7.53k
    }
38
39
882
    return res;
40
882
}
41
42
std::string UrlEncode(std::string_view str)
43
0
{
44
0
    std::string res;
45
0
    res.reserve(str.size() * 3); // worst case: every char needs encoding
46
47
0
    for (char ch : str) {
  Branch (47:18): [True: 0, False: 0]
48
0
        auto c = static_cast<unsigned char>(ch);
49
        // Unreserved characters per RFC 3986, Section 2.3
50
0
        if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
  Branch (50:14): [True: 0, False: 0]
  Branch (50:26): [True: 0, False: 0]
  Branch (50:40): [True: 0, False: 0]
  Branch (50:52): [True: 0, False: 0]
51
0
            (c >= '0' && c <= '9') || c == '-' || c == '_' || c == '.' || c == '~') {
  Branch (51:14): [True: 0, False: 0]
  Branch (51:26): [True: 0, False: 0]
  Branch (51:39): [True: 0, False: 0]
  Branch (51:51): [True: 0, False: 0]
  Branch (51:63): [True: 0, False: 0]
  Branch (51:75): [True: 0, False: 0]
52
0
            res += ch;
53
0
        } else {
54
            // Percent-encode all other characters
55
0
            res += '%';
56
0
            constexpr char hex_chars[] = "0123456789ABCDEF";
57
0
            res += hex_chars[(c >> 4) & 0xF];
58
0
            res += hex_chars[c & 0xF];
59
0
        }
60
0
    }
61
0
    return res;
62
0
}