aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--depends/packages/bdb.mk2
-rw-r--r--doc/release-notes.md7
-rw-r--r--src/httpserver.cpp3
-rw-r--r--src/outputtype.cpp2
-rw-r--r--src/rest.cpp12
-rw-r--r--src/test/httpserver_tests.cpp4
-rw-r--r--src/wallet/rpc/backup.cpp2
-rw-r--r--src/wallet/rpc/wallet.cpp6
-rwxr-xr-xtest/functional/interface_rest.py4
9 files changed, 33 insertions, 9 deletions
diff --git a/depends/packages/bdb.mk b/depends/packages/bdb.mk
index 2370c5b759..c650c9bf44 100644
--- a/depends/packages/bdb.mk
+++ b/depends/packages/bdb.mk
@@ -14,7 +14,7 @@ $(package)_config_opts_freebsd=--with-pic
$(package)_config_opts_netbsd=--with-pic
$(package)_config_opts_openbsd=--with-pic
$(package)_config_opts_android=--with-pic
-$(package)_cflags+=-Wno-error=implicit-function-declaration -Wno-error=format-security
+$(package)_cflags+=-Wno-error=implicit-function-declaration -Wno-error=format-security -Wno-error=implicit-int
$(package)_cppflags_mingw32=-DUNICODE -D_UNICODE
endef
diff --git a/doc/release-notes.md b/doc/release-notes.md
index 19f604c66b..970e248618 100644
--- a/doc/release-notes.md
+++ b/doc/release-notes.md
@@ -45,10 +45,13 @@ unsupported systems.
### RPC and other APIs
- #26515 rpc: Require NodeStateStats object in getpeerinfo
+- #27279 doc: fix/improve warning helps in {create,load,unload,restore}wallet
+- #27468 rest: avoid segfault for invalid URI
### Build System
- #26944 depends: fix systemtap download URL
+- #27462 depends: fix compiling bdb with clang-16 on aarch64
### Wallet
@@ -58,6 +61,7 @@ unsupported systems.
- #26761 wallet: fully migrate address book entries for watchonly/solvable wallets
- #27053 wallet: reuse change dest when re-creating TX with avoidpartialspends
- #27080 wallet: Zero out wallet master key upon locking so it doesn't persist in memory
+- #27473 wallet: Properly handle "unknown" Address Type
### GUI changes
@@ -77,11 +81,14 @@ Thanks to everyone who directly contributed to this release:
- Andrew Chow
- Hennadii Stepanov
- John Moffett
+- Jon Atack
- Marco Falke
- Martin Zumsande
- Matthew Zipkin
- Michael Ford
+- pablomartin4btc
- Sebastian Falbesoner
+- Thomas Nguyen
- Vasil Dimov
As well as to everyone that helped with translations on
diff --git a/src/httpserver.cpp b/src/httpserver.cpp
index e68436cc2c..fce15bf4df 100644
--- a/src/httpserver.cpp
+++ b/src/httpserver.cpp
@@ -652,6 +652,9 @@ std::optional<std::string> HTTPRequest::GetQueryParameter(const std::string& key
std::optional<std::string> GetQueryParameterFromUri(const char* uri, const std::string& key)
{
evhttp_uri* uri_parsed{evhttp_uri_parse(uri)};
+ if (!uri_parsed) {
+ throw std::runtime_error("URI parsing failed, it likely contained RFC 3986 invalid characters");
+ }
const char* query{evhttp_uri_get_query(uri_parsed)};
std::optional<std::string> result;
diff --git a/src/outputtype.cpp b/src/outputtype.cpp
index 9ab2902256..e95ec7f4d3 100644
--- a/src/outputtype.cpp
+++ b/src/outputtype.cpp
@@ -32,8 +32,6 @@ std::optional<OutputType> ParseOutputType(const std::string& type)
return OutputType::BECH32;
} else if (type == OUTPUT_TYPE_STRING_BECH32M) {
return OutputType::BECH32M;
- } else if (type == OUTPUT_TYPE_STRING_UNKNOWN) {
- return OutputType::UNKNOWN;
}
return std::nullopt;
}
diff --git a/src/rest.cpp b/src/rest.cpp
index 7f00db2222..56b6fbd175 100644
--- a/src/rest.cpp
+++ b/src/rest.cpp
@@ -200,7 +200,11 @@ static bool rest_headers(const std::any& context,
} else if (path.size() == 1) {
// new path with query parameter: /rest/headers/<hash>?count=<count>
hashStr = path[0];
- raw_count = req->GetQueryParameter("count").value_or("5");
+ try {
+ raw_count = req->GetQueryParameter("count").value_or("5");
+ } catch (const std::runtime_error& e) {
+ return RESTERR(req, HTTP_BAD_REQUEST, e.what());
+ }
} else {
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid URI format. Expected /rest/headers/<hash>.<ext>?count=<count>");
}
@@ -369,7 +373,11 @@ static bool rest_filter_header(const std::any& context, HTTPRequest* req, const
} else if (uri_parts.size() == 2) {
// new path with query parameter: /rest/blockfilterheaders/<filtertype>/<blockhash>?count=<count>
raw_blockhash = uri_parts[1];
- raw_count = req->GetQueryParameter("count").value_or("5");
+ try {
+ raw_count = req->GetQueryParameter("count").value_or("5");
+ } catch (const std::runtime_error& e) {
+ return RESTERR(req, HTTP_BAD_REQUEST, e.what());
+ }
} else {
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid URI format. Expected /rest/blockfilterheaders/<filtertype>/<blockhash>.<ext>?count=<count>");
}
diff --git a/src/test/httpserver_tests.cpp b/src/test/httpserver_tests.cpp
index ee59ec6967..c95a777e80 100644
--- a/src/test/httpserver_tests.cpp
+++ b/src/test/httpserver_tests.cpp
@@ -34,5 +34,9 @@ BOOST_AUTO_TEST_CASE(test_query_parameters)
// Invalid query string syntax is the same as not having parameters
uri = "/rest/endpoint/someresource.json&p1=v1&p2=v2";
BOOST_CHECK(!GetQueryParameterFromUri(uri.c_str(), "p1").has_value());
+
+ // URI with invalid characters (%) raises a runtime error regardless of which query parameter is queried
+ uri = "/rest/endpoint/someresource.json&p1=v1&p2=v2%";
+ BOOST_CHECK_EXCEPTION(GetQueryParameterFromUri(uri.c_str(), "p1"), std::runtime_error, HasReason("URI parsing failed, it likely contained RFC 3986 invalid characters"));
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/wallet/rpc/backup.cpp b/src/wallet/rpc/backup.cpp
index a971331a70..bebd47356a 100644
--- a/src/wallet/rpc/backup.cpp
+++ b/src/wallet/rpc/backup.cpp
@@ -1886,7 +1886,7 @@ RPCHelpMan restorewallet()
RPCResult::Type::OBJ, "", "",
{
{RPCResult::Type::STR, "name", "The wallet name if restored successfully."},
- {RPCResult::Type::STR, "warning", "Warning message if wallet was not loaded cleanly."},
+ {RPCResult::Type::STR, "warning", "Warning messages, if any, related to restoring the wallet. Multiple messages will be delimited by newlines."},
}
},
RPCExamples{
diff --git a/src/wallet/rpc/wallet.cpp b/src/wallet/rpc/wallet.cpp
index a2ae078343..dfa136e442 100644
--- a/src/wallet/rpc/wallet.cpp
+++ b/src/wallet/rpc/wallet.cpp
@@ -207,7 +207,7 @@ static RPCHelpMan loadwallet()
RPCResult::Type::OBJ, "", "",
{
{RPCResult::Type::STR, "name", "The wallet name if loaded successfully."},
- {RPCResult::Type::STR, "warning", "Warning message if wallet was not loaded cleanly."},
+ {RPCResult::Type::STR, "warning", "Warning messages, if any, related to loading the wallet. Multiple messages will be delimited by newlines."},
}
},
RPCExamples{
@@ -327,7 +327,7 @@ static RPCHelpMan createwallet()
RPCResult::Type::OBJ, "", "",
{
{RPCResult::Type::STR, "name", "The wallet name if created successfully. If the wallet was created using a full path, the wallet_name will be the full path."},
- {RPCResult::Type::STR, "warning", "Warning message if wallet was not loaded cleanly."},
+ {RPCResult::Type::STR, "warning", "Warning messages, if any, related to creating the wallet. Multiple messages will be delimited by newlines."},
}
},
RPCExamples{
@@ -414,7 +414,7 @@ static RPCHelpMan unloadwallet()
{"load_on_startup", RPCArg::Type::BOOL, RPCArg::Optional::OMITTED_NAMED_ARG, "Save wallet name to persistent settings and load on startup. True to add wallet to startup list, false to remove, null to leave unchanged."},
},
RPCResult{RPCResult::Type::OBJ, "", "", {
- {RPCResult::Type::STR, "warning", "Warning message if wallet was not unloaded cleanly."},
+ {RPCResult::Type::STR, "warning", "Warning messages, if any, related to unloading the wallet. Multiple messages will be delimited by newlines."},
}},
RPCExamples{
HelpExampleCli("unloadwallet", "wallet_name")
diff --git a/test/functional/interface_rest.py b/test/functional/interface_rest.py
index f36bbda3af..cb1fbdfb7a 100755
--- a/test/functional/interface_rest.py
+++ b/test/functional/interface_rest.py
@@ -281,6 +281,10 @@ class RESTTest (BitcoinTestFramework):
assert_equal(len(json_obj), 1) # ensure that there is one header in the json response
assert_equal(json_obj[0]['hash'], bb_hash) # request/response hash should be the same
+ # Check invalid uri (% symbol at the end of the request)
+ resp = self.test_rest_request(f"/headers/{bb_hash}%", ret_type=RetType.OBJ, status=400)
+ assert_equal(resp.read().decode('utf-8').rstrip(), "URI parsing failed, it likely contained RFC 3986 invalid characters")
+
# Compare with normal RPC block response
rpc_block_json = self.nodes[0].getblock(bb_hash)
for key in ['hash', 'confirmations', 'height', 'version', 'merkleroot', 'time', 'nonce', 'bits', 'difficulty', 'chainwork', 'previousblockhash']: