rpc: avoid descriptor range counter overflow

Descriptor ranges may end at `INT32_MAX`, but the expansion loop counts with `int`.
Incrementing after the final index overflows, terminating the node in `-ftrapv` builds and invoking undefined behavior otherwise.

Use `int64_t` so the final increment stays representable.
This commit is contained in:
Lőrinc
2026-08-03 11:56:47 -07:00
parent 143a13fb2b
commit 264555af3c
2 changed files with 2 additions and 2 deletions

View File

@@ -1362,7 +1362,7 @@ std::vector<CScript> EvalDescriptorStringOrObject(const UniValue& scanobject, Fl
range.second = 0;
}
std::vector<CScript> ret;
for (int i = range.first; i <= range.second; ++i) {
for (int64_t i = range.first; i <= range.second; ++i) {
for (const auto& desc : descs) {
std::vector<CScript> scripts;
if (!desc->Expand(i, provider, scripts, provider)) {

View File

@@ -80,7 +80,7 @@ class ScantxoutsetTest(BitcoinTestFramework):
assert_raises_rpc_error(-8, "End of range is too high", self.nodes[0].scantxoutset, "start", [{"desc": "desc", "range": [(2 << 31 + 1) - 1000000, (2 << 31 + 1)]}])
assert_raises_rpc_error(-8, "Range specified as [begin,end] must not have begin after end", self.nodes[0].scantxoutset, "start", [{"desc": "desc", "range": [2, 1]}])
assert_raises_rpc_error(-8, "Range is too large", self.nodes[0].scantxoutset, "start", [{"desc": "desc", "range": [0, 1000001]}])
range_end = 2**31 - 2 # TODO: The largest accepted endpoint overflows the expansion counter.
range_end = 2**31 - 1
assert_equal(self.nodes[0].scantxoutset("start", [{"desc": "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0h/0'/*)", "range": [range_end, range_end]}])['success'], True)
self.log.info("Test extended key derivation.")