aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorFabian Jahr <fjahr@protonmail.com>2024-04-20 16:35:39 +0200
committerFabian Jahr <fjahr@protonmail.com>2024-04-24 23:23:34 +0200
commit650d43ec15f7a3ae38126f65ef8fa0b1fd3ee936 (patch)
tree3d5b7a9d7f8a15e467ea6694c323152f683b080b /src/common
parent46bc6c2aaa613eef526b21a06bf21e8edde31a88 (diff)
downloadbitcoin-650d43ec15f7a3ae38126f65ef8fa0b1fd3ee936.tar.xz
refactor: Replace libevent use in urlDecode with our own code
Diffstat (limited to 'src/common')
-rw-r--r--src/common/url.cpp40
-rw-r--r--src/common/url.h3
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;