/tmp/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 <string> |
9 | | #include <string_view> |
10 | | #include <system_error> |
11 | | |
12 | | std::string UrlDecode(std::string_view url_encoded) |
13 | 14.8k | { |
14 | 14.8k | std::string res; |
15 | 14.8k | res.reserve(url_encoded.size()); |
16 | | |
17 | 215k | for (size_t i = 0; i < url_encoded.size(); ++i) { |
18 | 200k | 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 | 200k | if (c == '%' && i + 2 < url_encoded.size()) { |
22 | 220 | unsigned int decoded_value{0}; |
23 | 220 | 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 | 220 | if (ec == std::errc{} && p == url_encoded.data() + i + 3) { |
28 | 201 | res += static_cast<char>(decoded_value); |
29 | | // Next two characters are part of the percent encoding |
30 | 201 | i += 2; |
31 | 201 | continue; |
32 | 201 | } |
33 | | // In case of invalid percent encoding, add the '%' and continue |
34 | 220 | } |
35 | 200k | res += c; |
36 | 200k | } |
37 | | |
38 | 14.8k | return res; |
39 | 14.8k | } |