Bitcoin Core 31.99.0
P2P Digital Currency
url.cpp
Go to the documentation of this file.
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 <string>
9#include <string_view>
10#include <system_error>
11
12std::string UrlDecode(std::string_view url_encoded)
13{
14 std::string res;
15 res.reserve(url_encoded.size());
16
17 for (size_t i = 0; i < url_encoded.size(); ++i) {
18 char c = url_encoded[i];
19 // Special handling for percent which should be followed by two hex digits
20 // representing an octet values, see RFC 3986, Section 2.1 Percent-Encoding
21 if (c == '%' && i + 2 < url_encoded.size()) {
22 unsigned int decoded_value{0};
23 auto [p, ec] = std::from_chars(url_encoded.data() + i + 1, url_encoded.data() + i + 3, decoded_value, 16);
24
25 // Only if there is no error and the pointer is set to the end of
26 // the string, we can be sure both characters were valid hex
27 if (ec == std::errc{} && p == url_encoded.data() + i + 3) {
28 res += static_cast<char>(decoded_value);
29 // Next two characters are part of the percent encoding
30 i += 2;
31 continue;
32 }
33 // In case of invalid percent encoding, add the '%' and continue
34 }
35 res += c;
36 }
37
38 return res;
39}
40
41std::string UrlEncode(std::string_view str)
42{
43 std::string res;
44 res.reserve(str.size() * 3); // worst case: every char needs encoding
45
46 for (char ch : str) {
47 auto c = static_cast<unsigned char>(ch);
48 // Unreserved characters per RFC 3986, Section 2.3
49 if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
50 (c >= '0' && c <= '9') || c == '-' || c == '_' || c == '.' || c == '~') {
51 res += ch;
52 } else {
53 // Percent-encode all other characters
54 res += '%';
55 constexpr char hex_chars[] = "0123456789ABCDEF";
56 res += hex_chars[(c >> 4) & 0xF];
57 res += hex_chars[c & 0xF];
58 }
59 }
60 return res;
61}
std::string UrlDecode(std::string_view url_encoded)
Definition: url.cpp:12
std::string UrlEncode(std::string_view str)
Definition: url.cpp:41