2022-12-24 23:49:50 +00:00
|
|
|
// Copyright (c) 2015-2022 The Bitcoin Core developers
|
2019-04-02 17:03:37 -04:00
|
|
|
// Distributed under the MIT software license, see the accompanying
|
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
|
2022-10-14 13:55:53 +08:00
|
|
|
#include <common/url.h>
|
2019-04-02 17:03:37 -04:00
|
|
|
|
2024-04-20 16:35:39 +02:00
|
|
|
#include <charconv>
|
2019-04-02 17:03:37 -04:00
|
|
|
#include <string>
|
2024-04-20 16:35:39 +02:00
|
|
|
#include <string_view>
|
|
|
|
|
#include <system_error>
|
2019-04-02 17:03:37 -04:00
|
|
|
|
2024-04-20 17:05:18 +02:00
|
|
|
std::string UrlDecode(std::string_view url_encoded)
|
2024-04-20 16:35:39 +02:00
|
|
|
{
|
2019-04-02 17:03:37 -04:00
|
|
|
std::string res;
|
2024-04-20 17:05:18 +02:00
|
|
|
res.reserve(url_encoded.size());
|
2024-04-20 16:35:39 +02:00
|
|
|
|
2024-04-20 17:05:18 +02:00
|
|
|
for (size_t i = 0; i < url_encoded.size(); ++i) {
|
|
|
|
|
char c = url_encoded[i];
|
2024-04-20 16:35:39 +02:00
|
|
|
// Special handling for percent which should be followed by two hex digits
|
|
|
|
|
// representing an octet values, see RFC 3986, Section 2.1 Percent-Encoding
|
2024-04-20 17:05:18 +02:00
|
|
|
if (c == '%' && i + 2 < url_encoded.size()) {
|
2024-04-20 16:35:39 +02:00
|
|
|
unsigned int decoded_value{0};
|
2024-04-20 17:05:18 +02:00
|
|
|
auto [p, ec] = std::from_chars(url_encoded.data() + i + 1, url_encoded.data() + i + 3, decoded_value, 16);
|
2024-04-20 16:35:39 +02:00
|
|
|
|
|
|
|
|
// Only if there is no error and the pointer is set to the end of
|
|
|
|
|
// the string, we can be sure both characters were valid hex
|
2024-04-20 17:05:18 +02:00
|
|
|
if (ec == std::errc{} && p == url_encoded.data() + i + 3) {
|
2024-04-20 16:35:39 +02:00
|
|
|
res += static_cast<char>(decoded_value);
|
|
|
|
|
// Next two characters are part of the percent encoding
|
|
|
|
|
i += 2;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
// In case of invalid percent encoding, add the '%' and continue
|
2019-04-02 17:03:37 -04:00
|
|
|
}
|
2024-04-20 16:35:39 +02:00
|
|
|
res += c;
|
2019-04-02 17:03:37 -04:00
|
|
|
}
|
2024-04-20 16:35:39 +02:00
|
|
|
|
2019-04-02 17:03:37 -04:00
|
|
|
return res;
|
|
|
|
|
}
|