Skip to content

Commit 810ce36

Browse files
author
MarcoFalke
committed
Merge bitcoin/bitcoin#23213: rest: Return error when header count is not integral
fa8d492 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 fa8d492 promag: Code review ACK fa8d492. shaavan: Code Review ACK fa8d492 Tree-SHA512: d6335b132ca2010fb8cae311dd936b2dea99a5bd0e6b2556a604f93698b8456df9190c5151345a03344243ede4aad0e2526cedc2aa8b5b1b8e8ce786cb3b6e50
2 parents 8df7eee + fa8d492 commit 810ce36

File tree

3 files changed

+14
-6
lines changed

3 files changed

+14
-6
lines changed

src/rest.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,18 +189,19 @@ static bool rest_headers(const std::any& context,
189189
if (path.size() != 2)
190190
return RESTERR(req, HTTP_BAD_REQUEST, "No header count specified. Use /rest/headers/<count>/<hash>.<ext>.");
191191

192-
long count = strtol(path[0].c_str(), nullptr, 10);
193-
if (count < 1 || count > 2000)
192+
const auto parsed_count{ToIntegral<size_t>(path[0])};
193+
if (!parsed_count.has_value() || *parsed_count < 1 || *parsed_count > 2000) {
194194
return RESTERR(req, HTTP_BAD_REQUEST, "Header count out of range: " + path[0]);
195+
}
195196

196197
std::string hashStr = path[1];
197198
uint256 hash;
198199
if (!ParseHashStr(hashStr, hash))
199200
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
200201

201202
const CBlockIndex* tip = nullptr;
202-
std::vector<const CBlockIndex *> headers;
203-
headers.reserve(count);
203+
std::vector<const CBlockIndex*> headers;
204+
headers.reserve(*parsed_count);
204205
{
205206
ChainstateManager* maybe_chainman = GetChainman(context, req);
206207
if (!maybe_chainman) return false;
@@ -211,8 +212,9 @@ static bool rest_headers(const std::any& context,
211212
const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(hash);
212213
while (pindex != nullptr && active_chain.Contains(pindex)) {
213214
headers.push_back(pindex);
214-
if (headers.size() == (unsigned long)count)
215+
if (headers.size() == *parsed_count) {
215216
break;
217+
}
216218
pindex = active_chain.Next(pindex);
217219
}
218220
}

test/functional/interface_rest.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,13 @@ def run_test(self):
279279
json_obj = self.test_rest_request(f"/headers/5/{bb_hash}")
280280
assert_equal(len(json_obj), 5) # now we should have 5 header objects
281281

282+
# Test number parsing
283+
for num in ['5a', '-5', '0', '2001', '99999999999999999999999999999999999']:
284+
assert_equal(
285+
bytes(f'Header count out of range: {num}\r\n', 'ascii'),
286+
self.test_rest_request(f"/headers/{num}/{bb_hash}", ret_type=RetType.BYTES, status=400),
287+
)
288+
282289
self.log.info("Test tx inclusion in the /mempool and /block URIs")
283290

284291
# Make 3 tx and mine them on node 1

test/lint/lint-locale-dependence.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ export LC_ALL=C
4343
KNOWN_VIOLATIONS=(
4444
"src/bitcoin-tx.cpp.*stoul"
4545
"src/dbwrapper.cpp:.*vsnprintf"
46-
"src/rest.cpp:.*strtol"
4746
"src/test/dbwrapper_tests.cpp:.*snprintf"
4847
"src/test/fuzz/locale.cpp"
4948
"src/test/fuzz/string.cpp"

0 commit comments

Comments
 (0)