mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-05 14:06:27 -05:00
Merge bitcoin/bitcoin#27474: [24.x] Additional backports for 24.1
dc711fbd32
doc: update 24.1 release notes (fanquake)fc8c1a8deb
doc: fix/improve warning helps in {create,load,unload,restore}wallet (Jon Atack)3a26b19df2
bugfix: rest: avoid segfault for invalid URI (pablomartin4btc)c40b1da2fd
depends: fix compiling bdb with clang-16 on aarch64 (fanquake)0bac52d5cf
Don't return OutputType::UNKNOWN in ParseOutputType (Pttn) Pull request description: Backports: * https://github.com/bitcoin/bitcoin/pull/27279 (onlyf73782a903
) * https://github.com/bitcoin/bitcoin/pull/27462 * https://github.com/bitcoin/bitcoin/pull/27468 * https://github.com/bitcoin/bitcoin/pull/27473 ACKs for top commit: stickies-v: ACKdc711fbd32
hebasto: re-ACKdc711fbd32
jonatack: ACKdc711fbd32
Tree-SHA512: 72c673be82689e3c3a1c2564a1fdd6afe0b357b7aa8bec9524fe6999804fbccf310da0b074e647af14b753e5e695024e268fe4f69aa58747f541f7f429ebede6
This commit is contained in:
commit
15a24781d0
9 changed files with 33 additions and 9 deletions
|
@ -14,7 +14,7 @@ $(package)_config_opts_freebsd=--with-pic
|
||||||
$(package)_config_opts_netbsd=--with-pic
|
$(package)_config_opts_netbsd=--with-pic
|
||||||
$(package)_config_opts_openbsd=--with-pic
|
$(package)_config_opts_openbsd=--with-pic
|
||||||
$(package)_config_opts_android=--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
|
$(package)_cppflags_mingw32=-DUNICODE -D_UNICODE
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
|
|
@ -45,10 +45,13 @@ unsupported systems.
|
||||||
### RPC and other APIs
|
### RPC and other APIs
|
||||||
|
|
||||||
- #26515 rpc: Require NodeStateStats object in getpeerinfo
|
- #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
|
### Build System
|
||||||
|
|
||||||
- #26944 depends: fix systemtap download URL
|
- #26944 depends: fix systemtap download URL
|
||||||
|
- #27462 depends: fix compiling bdb with clang-16 on aarch64
|
||||||
|
|
||||||
### Wallet
|
### Wallet
|
||||||
|
|
||||||
|
@ -58,6 +61,7 @@ unsupported systems.
|
||||||
- #26761 wallet: fully migrate address book entries for watchonly/solvable wallets
|
- #26761 wallet: fully migrate address book entries for watchonly/solvable wallets
|
||||||
- #27053 wallet: reuse change dest when re-creating TX with avoidpartialspends
|
- #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
|
- #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
|
### GUI changes
|
||||||
|
|
||||||
|
@ -77,11 +81,14 @@ Thanks to everyone who directly contributed to this release:
|
||||||
- Andrew Chow
|
- Andrew Chow
|
||||||
- Hennadii Stepanov
|
- Hennadii Stepanov
|
||||||
- John Moffett
|
- John Moffett
|
||||||
|
- Jon Atack
|
||||||
- Marco Falke
|
- Marco Falke
|
||||||
- Martin Zumsande
|
- Martin Zumsande
|
||||||
- Matthew Zipkin
|
- Matthew Zipkin
|
||||||
- Michael Ford
|
- Michael Ford
|
||||||
|
- pablomartin4btc
|
||||||
- Sebastian Falbesoner
|
- Sebastian Falbesoner
|
||||||
|
- Thomas Nguyen
|
||||||
- Vasil Dimov
|
- Vasil Dimov
|
||||||
|
|
||||||
As well as to everyone that helped with translations on
|
As well as to everyone that helped with translations on
|
||||||
|
|
|
@ -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)
|
std::optional<std::string> GetQueryParameterFromUri(const char* uri, const std::string& key)
|
||||||
{
|
{
|
||||||
evhttp_uri* uri_parsed{evhttp_uri_parse(uri)};
|
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)};
|
const char* query{evhttp_uri_get_query(uri_parsed)};
|
||||||
std::optional<std::string> result;
|
std::optional<std::string> result;
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,6 @@ std::optional<OutputType> ParseOutputType(const std::string& type)
|
||||||
return OutputType::BECH32;
|
return OutputType::BECH32;
|
||||||
} else if (type == OUTPUT_TYPE_STRING_BECH32M) {
|
} else if (type == OUTPUT_TYPE_STRING_BECH32M) {
|
||||||
return OutputType::BECH32M;
|
return OutputType::BECH32M;
|
||||||
} else if (type == OUTPUT_TYPE_STRING_UNKNOWN) {
|
|
||||||
return OutputType::UNKNOWN;
|
|
||||||
}
|
}
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
12
src/rest.cpp
12
src/rest.cpp
|
@ -200,7 +200,11 @@ static bool rest_headers(const std::any& context,
|
||||||
} else if (path.size() == 1) {
|
} else if (path.size() == 1) {
|
||||||
// new path with query parameter: /rest/headers/<hash>?count=<count>
|
// new path with query parameter: /rest/headers/<hash>?count=<count>
|
||||||
hashStr = path[0];
|
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 {
|
} else {
|
||||||
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid URI format. Expected /rest/headers/<hash>.<ext>?count=<count>");
|
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) {
|
} else if (uri_parts.size() == 2) {
|
||||||
// new path with query parameter: /rest/blockfilterheaders/<filtertype>/<blockhash>?count=<count>
|
// new path with query parameter: /rest/blockfilterheaders/<filtertype>/<blockhash>?count=<count>
|
||||||
raw_blockhash = uri_parts[1];
|
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 {
|
} else {
|
||||||
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid URI format. Expected /rest/blockfilterheaders/<filtertype>/<blockhash>.<ext>?count=<count>");
|
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid URI format. Expected /rest/blockfilterheaders/<filtertype>/<blockhash>.<ext>?count=<count>");
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,5 +34,9 @@ BOOST_AUTO_TEST_CASE(test_query_parameters)
|
||||||
// Invalid query string syntax is the same as not having parameters
|
// Invalid query string syntax is the same as not having parameters
|
||||||
uri = "/rest/endpoint/someresource.json&p1=v1&p2=v2";
|
uri = "/rest/endpoint/someresource.json&p1=v1&p2=v2";
|
||||||
BOOST_CHECK(!GetQueryParameterFromUri(uri.c_str(), "p1").has_value());
|
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()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
|
@ -1886,7 +1886,7 @@ RPCHelpMan restorewallet()
|
||||||
RPCResult::Type::OBJ, "", "",
|
RPCResult::Type::OBJ, "", "",
|
||||||
{
|
{
|
||||||
{RPCResult::Type::STR, "name", "The wallet name if restored successfully."},
|
{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{
|
RPCExamples{
|
||||||
|
|
|
@ -207,7 +207,7 @@ static RPCHelpMan loadwallet()
|
||||||
RPCResult::Type::OBJ, "", "",
|
RPCResult::Type::OBJ, "", "",
|
||||||
{
|
{
|
||||||
{RPCResult::Type::STR, "name", "The wallet name if loaded successfully."},
|
{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{
|
RPCExamples{
|
||||||
|
@ -327,7 +327,7 @@ static RPCHelpMan createwallet()
|
||||||
RPCResult::Type::OBJ, "", "",
|
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, "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{
|
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."},
|
{"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{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{
|
RPCExamples{
|
||||||
HelpExampleCli("unloadwallet", "wallet_name")
|
HelpExampleCli("unloadwallet", "wallet_name")
|
||||||
|
|
|
@ -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(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
|
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
|
# Compare with normal RPC block response
|
||||||
rpc_block_json = self.nodes[0].getblock(bb_hash)
|
rpc_block_json = self.nodes[0].getblock(bb_hash)
|
||||||
for key in ['hash', 'confirmations', 'height', 'version', 'merkleroot', 'time', 'nonce', 'bits', 'difficulty', 'chainwork', 'previousblockhash']:
|
for key in ['hash', 'confirmations', 'height', 'version', 'merkleroot', 'time', 'nonce', 'bits', 'difficulty', 'chainwork', 'previousblockhash']:
|
||||||
|
|
Loading…
Add table
Reference in a new issue