Branch data Line data Source code
1 : : // Copyright (c) 2015-2022 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 : 840 : std::string UrlDecode(std::string_view url_encoded)
13 : : {
14 [ + - ]: 840 : std::string res;
15 [ + - ]: 840 : res.reserve(url_encoded.size());
16 : :
17 [ + + ]: 8852 : for (size_t i = 0; i < url_encoded.size(); ++i) {
18 [ + + ]: 8012 : 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 [ + + + + ]: 8012 : if (c == '%' && i + 2 < url_encoded.size()) {
22 : 255 : unsigned int decoded_value{0};
23 : 255 : 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 [ + + + + ]: 255 : if (ec == std::errc{} && p == url_encoded.data() + i + 3) {
28 [ + - ]: 102 : res += static_cast<char>(decoded_value);
29 : : // Next two characters are part of the percent encoding
30 : 102 : i += 2;
31 : 102 : continue;
32 : : }
33 : : // In case of invalid percent encoding, add the '%' and continue
34 : : }
35 [ + - ]: 15922 : res += c;
36 : : }
37 : :
38 : 840 : return res;
39 : 0 : }
|