aboutsummaryrefslogtreecommitdiff
path: root/src/common/url.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/url.cpp')
-rw-r--r--src/common/url.cpp35
1 files changed, 26 insertions, 9 deletions
diff --git a/src/common/url.cpp b/src/common/url.cpp
index 053e1a825c..ecf88d07ea 100644
--- a/src/common/url.cpp
+++ b/src/common/url.cpp
@@ -4,19 +4,36 @@
#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 url_encoded)
+{
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(url_encoded.size());
+
+ for (size_t i = 0; i < url_encoded.size(); ++i) {
+ char c = url_encoded[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 < url_encoded.size()) {
+ unsigned int decoded_value{0};
+ auto [p, ec] = std::from_chars(url_encoded.data() + i + 1, url_encoded.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 == url_encoded.data() + i + 3) {
+ 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;
}