diff options
author | Fabian Jahr <fjahr@protonmail.com> | 2024-04-20 16:35:39 +0200 |
---|---|---|
committer | Fabian Jahr <fjahr@protonmail.com> | 2024-04-24 23:23:34 +0200 |
commit | 650d43ec15f7a3ae38126f65ef8fa0b1fd3ee936 (patch) | |
tree | 3d5b7a9d7f8a15e467ea6694c323152f683b080b /src/common | |
parent | 46bc6c2aaa613eef526b21a06bf21e8edde31a88 (diff) | |
download | bitcoin-650d43ec15f7a3ae38126f65ef8fa0b1fd3ee936.tar.xz |
refactor: Replace libevent use in urlDecode with our own code
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/url.cpp | 40 | ||||
-rw-r--r-- | src/common/url.h | 3 |
2 files changed, 33 insertions, 10 deletions
diff --git a/src/common/url.cpp b/src/common/url.cpp index 053e1a825c..d0bf4e0cbe 100644 --- a/src/common/url.cpp +++ b/src/common/url.cpp @@ -4,19 +4,41 @@ #include <common/url.h> -#include <event2/http.h> - -#include <cstdlib> +#include <charconv> #include <string> +#include <string_view> +#include <system_error> -std::string urlDecode(const std::string &urlEncoded) { +std::string urlDecode(std::string_view urlEncoded) +{ std::string res; - if (!urlEncoded.empty()) { - char *decoded = evhttp_uridecode(urlEncoded.c_str(), false, nullptr); - if (decoded) { - res = std::string(decoded); - free(decoded); + res.reserve(urlEncoded.size()); + + for (size_t i = 0; i < urlEncoded.size(); ++i) { + char c = urlEncoded[i]; + // Special handling for percent which should be followed by two hex digits + // representing an octet values, see RFC 3986, Section 2.1 Percent-Encoding + if (c == '%' && i + 2 < urlEncoded.size()) { + unsigned int decoded_value{0}; + auto [p, ec] = std::from_chars(urlEncoded.data() + i + 1, urlEncoded.data() + i + 3, decoded_value, 16); + + // 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 + if (ec == std::errc{} && p == urlEncoded.data() + i + 3) { + // A null character terminates the string + if (decoded_value == 0) { + return res; + } + + 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 } + res += c; } + return res; } diff --git a/src/common/url.h b/src/common/url.h index b16b8241af..7b0a944776 100644 --- a/src/common/url.h +++ b/src/common/url.h @@ -6,8 +6,9 @@ #define BITCOIN_COMMON_URL_H #include <string> +#include <string_view> -using UrlDecodeFn = std::string(const std::string& url_encoded); +using UrlDecodeFn = std::string(std::string_view url_encoded); UrlDecodeFn urlDecode; extern UrlDecodeFn* const URL_DECODE; |