aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcoFalke <falke.marco@gmail.com>2021-10-12 14:39:19 +0200
committerMarcoFalke <falke.marco@gmail.com>2021-10-12 14:39:24 +0200
commit810ce36d54e4a047f27a099e8295ddadfced75a9 (patch)
tree668eff074be0a10a4290ed495826837172689dfc
parent8df7eee5e1c8ad6b224aa00bcfd7a04a974362c4 (diff)
parentfa8d49289479b8eda7ba7530515c414d1cd566a3 (diff)
downloadbitcoin-810ce36d54e4a047f27a099e8295ddadfced75a9.tar.xz
Merge bitcoin/bitcoin#23213: rest: Return error when header count is not integral
fa8d49289479b8eda7ba7530515c414d1cd566a3 rest: Return error when header count is not integral (MarcoFalke) Pull request description: Seems odd to interpret a hash (or any other string) as integer when it contains more than the digits 0 to 9. ACKs for top commit: practicalswift: cr ACK fa8d49289479b8eda7ba7530515c414d1cd566a3 promag: Code review ACK fa8d49289479b8eda7ba7530515c414d1cd566a3. shaavan: Code Review ACK fa8d49289479b8eda7ba7530515c414d1cd566a3 Tree-SHA512: d6335b132ca2010fb8cae311dd936b2dea99a5bd0e6b2556a604f93698b8456df9190c5151345a03344243ede4aad0e2526cedc2aa8b5b1b8e8ce786cb3b6e50
-rw-r--r--src/rest.cpp12
-rwxr-xr-xtest/functional/interface_rest.py7
-rwxr-xr-xtest/lint/lint-locale-dependence.sh1
3 files changed, 14 insertions, 6 deletions
diff --git a/src/rest.cpp b/src/rest.cpp
index e50ab33e54..f6e34c2d81 100644
--- a/src/rest.cpp
+++ b/src/rest.cpp
@@ -189,9 +189,10 @@ static bool rest_headers(const std::any& context,
if (path.size() != 2)
return RESTERR(req, HTTP_BAD_REQUEST, "No header count specified. Use /rest/headers/<count>/<hash>.<ext>.");
- long count = strtol(path[0].c_str(), nullptr, 10);
- if (count < 1 || count > 2000)
+ const auto parsed_count{ToIntegral<size_t>(path[0])};
+ if (!parsed_count.has_value() || *parsed_count < 1 || *parsed_count > 2000) {
return RESTERR(req, HTTP_BAD_REQUEST, "Header count out of range: " + path[0]);
+ }
std::string hashStr = path[1];
uint256 hash;
@@ -199,8 +200,8 @@ static bool rest_headers(const std::any& context,
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
const CBlockIndex* tip = nullptr;
- std::vector<const CBlockIndex *> headers;
- headers.reserve(count);
+ std::vector<const CBlockIndex*> headers;
+ headers.reserve(*parsed_count);
{
ChainstateManager* maybe_chainman = GetChainman(context, req);
if (!maybe_chainman) return false;
@@ -211,8 +212,9 @@ static bool rest_headers(const std::any& context,
const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(hash);
while (pindex != nullptr && active_chain.Contains(pindex)) {
headers.push_back(pindex);
- if (headers.size() == (unsigned long)count)
+ if (headers.size() == *parsed_count) {
break;
+ }
pindex = active_chain.Next(pindex);
}
}
diff --git a/test/functional/interface_rest.py b/test/functional/interface_rest.py
index e0716fc54a..adc33bd9df 100755
--- a/test/functional/interface_rest.py
+++ b/test/functional/interface_rest.py
@@ -279,6 +279,13 @@ class RESTTest (BitcoinTestFramework):
json_obj = self.test_rest_request(f"/headers/5/{bb_hash}")
assert_equal(len(json_obj), 5) # now we should have 5 header objects
+ # Test number parsing
+ for num in ['5a', '-5', '0', '2001', '99999999999999999999999999999999999']:
+ assert_equal(
+ bytes(f'Header count out of range: {num}\r\n', 'ascii'),
+ self.test_rest_request(f"/headers/{num}/{bb_hash}", ret_type=RetType.BYTES, status=400),
+ )
+
self.log.info("Test tx inclusion in the /mempool and /block URIs")
# Make 3 tx and mine them on node 1
diff --git a/test/lint/lint-locale-dependence.sh b/test/lint/lint-locale-dependence.sh
index f82d82f890..34022ece35 100755
--- a/test/lint/lint-locale-dependence.sh
+++ b/test/lint/lint-locale-dependence.sh
@@ -43,7 +43,6 @@ export LC_ALL=C
KNOWN_VIOLATIONS=(
"src/bitcoin-tx.cpp.*stoul"
"src/dbwrapper.cpp:.*vsnprintf"
- "src/rest.cpp:.*strtol"
"src/test/dbwrapper_tests.cpp:.*snprintf"
"src/test/fuzz/locale.cpp"
"src/test/fuzz/string.cpp"