Skip to content

Commit 650d43e

Browse files
committed
refactor: Replace libevent use in urlDecode with our own code
1 parent 46bc6c2 commit 650d43e

File tree

5 files changed

+37
-18
lines changed

5 files changed

+37
-18
lines changed

configure.ac

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1706,7 +1706,6 @@ AM_CONDITIONAL([ENABLE_QT_TESTS], [test "$BUILD_TEST_QT" = "yes"])
17061706
AM_CONDITIONAL([ENABLE_BENCH], [test "$use_bench" = "yes"])
17071707
AM_CONDITIONAL([USE_QRCODE], [test "$use_qr" = "yes"])
17081708
AM_CONDITIONAL([USE_LCOV], [test "$use_lcov" = "yes"])
1709-
AM_CONDITIONAL([USE_LIBEVENT], [test "$use_libevent" = "yes"])
17101709
AM_CONDITIONAL([HARDEN], [test "$use_hardening" = "yes"])
17111710
AM_CONDITIONAL([ENABLE_SSE42], [test "$enable_sse42" = "yes"])
17121711
AM_CONDITIONAL([ENABLE_SSE41], [test "$enable_sse41" = "yes"])

src/Makefile.am

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,7 @@ libbitcoin_common_a_SOURCES = \
679679
common/run_command.cpp \
680680
common/settings.cpp \
681681
common/system.cpp \
682+
common/url.cpp \
682683
compressor.cpp \
683684
core_read.cpp \
684685
core_write.cpp \
@@ -711,11 +712,6 @@ libbitcoin_common_a_SOURCES = \
711712
script/solver.cpp \
712713
warnings.cpp \
713714
$(BITCOIN_CORE_H)
714-
715-
if USE_LIBEVENT
716-
libbitcoin_common_a_CPPFLAGS += $(EVENT_CFLAGS)
717-
libbitcoin_common_a_SOURCES += common/url.cpp
718-
endif
719715
#
720716

721717
# util #

src/common/url.cpp

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,41 @@
44

55
#include <common/url.h>
66

7-
#include <event2/http.h>
8-
9-
#include <cstdlib>
7+
#include <charconv>
108
#include <string>
9+
#include <string_view>
10+
#include <system_error>
1111

12-
std::string urlDecode(const std::string &urlEncoded) {
12+
std::string urlDecode(std::string_view urlEncoded)
13+
{
1314
std::string res;
14-
if (!urlEncoded.empty()) {
15-
char *decoded = evhttp_uridecode(urlEncoded.c_str(), false, nullptr);
16-
if (decoded) {
17-
res = std::string(decoded);
18-
free(decoded);
15+
res.reserve(urlEncoded.size());
16+
17+
for (size_t i = 0; i < urlEncoded.size(); ++i) {
18+
char c = urlEncoded[i];
19+
// Special handling for percent which should be followed by two hex digits
20+
// representing an octet values, see RFC 3986, Section 2.1 Percent-Encoding
21+
if (c == '%' && i + 2 < urlEncoded.size()) {
22+
unsigned int decoded_value{0};
23+
auto [p, ec] = std::from_chars(urlEncoded.data() + i + 1, urlEncoded.data() + i + 3, decoded_value, 16);
24+
25+
// Only if there is no error and the pointer is set to the end of
26+
// the string, we can be sure both characters were valid hex
27+
if (ec == std::errc{} && p == urlEncoded.data() + i + 3) {
28+
// A null character terminates the string
29+
if (decoded_value == 0) {
30+
return res;
31+
}
32+
33+
res += static_cast<char>(decoded_value);
34+
// Next two characters are part of the percent encoding
35+
i += 2;
36+
continue;
37+
}
38+
// In case of invalid percent encoding, add the '%' and continue
1939
}
40+
res += c;
2041
}
42+
2143
return res;
2244
}

src/common/url.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
#define BITCOIN_COMMON_URL_H
77

88
#include <string>
9+
#include <string_view>
910

10-
using UrlDecodeFn = std::string(const std::string& url_encoded);
11+
using UrlDecodeFn = std::string(std::string_view url_encoded);
1112
UrlDecodeFn urlDecode;
1213
extern UrlDecodeFn* const URL_DECODE;
1314

src/wallet/rpc/util.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <wallet/context.h>
1212
#include <wallet/wallet.h>
1313

14+
#include <string_view>
1415
#include <univalue.h>
1516

1617
#include <boost/date_time/posix_time/posix_time.hpp>
@@ -61,9 +62,9 @@ bool ParseIncludeWatchonly(const UniValue& include_watchonly, const CWallet& wal
6162

6263
bool GetWalletNameFromJSONRPCRequest(const JSONRPCRequest& request, std::string& wallet_name)
6364
{
64-
if (URL_DECODE && request.URI.substr(0, WALLET_ENDPOINT_BASE.size()) == WALLET_ENDPOINT_BASE) {
65+
if (URL_DECODE && request.URI.starts_with(WALLET_ENDPOINT_BASE)) {
6566
// wallet endpoint was used
66-
wallet_name = URL_DECODE(request.URI.substr(WALLET_ENDPOINT_BASE.size()));
67+
wallet_name = URL_DECODE(std::string_view{request.URI}.substr(WALLET_ENDPOINT_BASE.size()));
6768
return true;
6869
}
6970
return false;

0 commit comments

Comments
 (0)