mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-04 10:12:28 +02:00
Merge bitcoin/bitcoin#29904: refactor: Use our own implementation of urlDecode
992c714451common: Don't terminate on null character in UrlDecode (Fabian Jahr)099fa57151scripted-diff: Modernize name of urlDecode function and param (Fabian Jahr)8f39aaae41refactor: Remove hooking code for urlDecode (Fabian Jahr)650d43ec15refactor: Replace libevent use in urlDecode with our own code (Fabian Jahr)46bc6c2aaatest: Add unit tests for urlDecode (Fabian Jahr) Pull request description: Fixes #29654 (as a side-effect) Removing dependencies is a general goal of the project and the xz backdoor has been an additional wake up call recently. Libevent shows many of the same symptoms, few maintainers and slow releases. While libevent can not be removed completely over night we should start removing it’s usage where it's possible, ideally with the end goal to removing it completely. This is a pretty easy win in that direction. The [`evhttp_uridecode` function from libevent](e0a4574ba2/http.c (L3542)) we were using in `urlDecode` could be easily emulated in fewer LOC. This also ports the [applicable test vectors over from libevent](https://github.com/libevent/libevent/blob/master/test/regress_http.c#L3430). ACKs for top commit: achow101: ACK992c714451theStack: Code-review ACK992c714451maflcko: ACK992c714451👈 stickies-v: ACK992c714451Tree-SHA512: 78f76ae7ab3b6710eab2aaac20f55eb0da7803e057eaa6220e865f328666a5399ef1a479702aaf630b2f974ad3aa15e2b6adac9c11bc8c3d4be21e8af1667fea
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -6,9 +6,12 @@
|
||||
#define BITCOIN_COMMON_URL_H
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
using UrlDecodeFn = std::string(const std::string& url_encoded);
|
||||
UrlDecodeFn urlDecode;
|
||||
extern UrlDecodeFn* const URL_DECODE;
|
||||
/* Decode a URL.
|
||||
*
|
||||
* Notably this implementation does not decode a '+' to a ' '.
|
||||
*/
|
||||
std::string UrlDecode(std::string_view url_encoded);
|
||||
|
||||
#endif // BITCOIN_COMMON_URL_H
|
||||
|
||||
Reference in New Issue
Block a user