/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 | } |