Skip to content

Commit 6144aa2

Browse files
committed
Merge bitcoin/bitcoin#30444: rest: Reject negative outpoint index early in getutxos parsing
fac932b refactor: Use util::Split to avoid a harmless unsigned-integer-overflow (MarcoFalke) fab54db rest: Reject negative outpoint index in getutxos parsing (MarcoFalke) Pull request description: In `rest_getutxos` outpoint indexes such as `+N` or `-N` are accepted. This should be harmless, because any index out of range should be treated as a non-existent utxo. However, a negative index can't exist ever, so it seems better to reject all signs, whether `+` or `-`. ACKs for top commit: achow101: ACK fac932b hodlinator: ut-ACK fac932b tdb3: re ACK fac932b danielabrozzoni: ACK fac932b brunoerg: reACK fac932b Tree-SHA512: 8f1a75248cb61e1c4beceded6ed170db83b07f30fbcf93a26acfffc00ec4546572366eff87907a7e1423d7d3a2a9e57a0a7a9bacb787c86463f842d7161c16bc
2 parents 20ccb30 + fac932b commit 6144aa2

File tree

2 files changed

+12
-6
lines changed

2 files changed

+12
-6
lines changed

src/rest.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -788,14 +788,17 @@ static bool rest_getutxos(const std::any& context, HTTPRequest* req, const std::
788788

789789
for (size_t i = (fCheckMemPool) ? 1 : 0; i < uriParts.size(); i++)
790790
{
791-
int32_t nOutput;
792-
std::string strTxid = uriParts[i].substr(0, uriParts[i].find('-'));
793-
std::string strOutput = uriParts[i].substr(uriParts[i].find('-')+1);
791+
const auto txid_out{util::Split<std::string_view>(uriParts[i], '-')};
792+
if (txid_out.size() != 2) {
793+
return RESTERR(req, HTTP_BAD_REQUEST, "Parse error");
794+
}
795+
auto output{ToIntegral<uint32_t>(txid_out.at(1))};
794796

795-
if (!ParseInt32(strOutput, &nOutput) || !IsHex(strTxid))
797+
if (!output || !IsHex(txid_out.at(0))) {
796798
return RESTERR(req, HTTP_BAD_REQUEST, "Parse error");
799+
}
797800

798-
vOutPoints.emplace_back(TxidFromString(strTxid), (uint32_t)nOutput);
801+
vOutPoints.emplace_back(TxidFromString(txid_out.at(0)), *output);
799802
}
800803

801804
if (vOutPoints.size() > 0)

test/functional/interface_rest.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,10 +201,13 @@ def run_test(self):
201201
json_obj = self.test_rest_request(f"/getutxos/checkmempool/{spending[0]}-{spending[1]}")
202202
assert_equal(len(json_obj['utxos']), 1)
203203

204-
# Do some invalid requests
204+
self.log.info("Check some invalid requests")
205205
self.test_rest_request("/getutxos", http_method='POST', req_type=ReqType.JSON, body='{"checkmempool', status=400, ret_type=RetType.OBJ)
206206
self.test_rest_request("/getutxos", http_method='POST', req_type=ReqType.BIN, body='{"checkmempool', status=400, ret_type=RetType.OBJ)
207207
self.test_rest_request("/getutxos/checkmempool", http_method='POST', req_type=ReqType.JSON, status=400, ret_type=RetType.OBJ)
208+
self.test_rest_request(f"/getutxos/{spending[0]}_+1", ret_type=RetType.OBJ, status=400)
209+
self.test_rest_request(f"/getutxos/{spending[0]}-+1", ret_type=RetType.OBJ, status=400)
210+
self.test_rest_request(f"/getutxos/{spending[0]}--1", ret_type=RetType.OBJ, status=400)
208211

209212
# Test limits
210213
long_uri = '/'.join([f"{txid}-{n_}" for n_ in range(20)])

0 commit comments

Comments
 (0)