Skip to content

Commit 2a2a269

Browse files
laanwjvijaydasmp
authored andcommitted
Merge bitcoin#23253: bitcoin-tx: Reject non-integral and out of range int strings
fa6f29d bitcoin-tx: Reject non-integral and out of range multisig numbers (MarcoFalke) fafab8e bitcoin-tx: Reject non-integral and out of range sequence ids (MarcoFalke) fa53d3d test: Check that bitcoin-tx accepts whitespace around sequence id and multisig numbers (MarcoFalke) Pull request description: Seems odd to silently accept arbitrary strings that don't even represent integral values. Fix that. ACKs for top commit: practicalswift: cr ACK fa6f29d laanwj: Code review ACK fa6f29d Empact: Code review ACK bitcoin@fa6f29d promag: Code review ACK fa6f29d. Tree-SHA512: e31f7f21fe55ac069e755557bdbcae8d5d29e20ff82e441ebdfc65153e3a31a4edd46ad3e6dea5190ecbd1b8ea5a8f94daa5d59a3b7558e46e794e30db0e6c79
1 parent 11eeae2 commit 2a2a269

File tree

2 files changed

+61
-6
lines changed

2 files changed

+61
-6
lines changed

src/bitcoin-tx.cpp

+15-4
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,16 @@ static void MutateTxLocktime(CMutableTransaction& tx, const std::string& cmdVal)
220220
tx.nLockTime = (unsigned int) newLocktime;
221221
}
222222

223+
template <typename T>
224+
static T TrimAndParse(const std::string& int_str, const std::string& err)
225+
{
226+
const auto parsed{ToIntegral<T>(TrimString(int_str))};
227+
if (!parsed.has_value()) {
228+
throw std::runtime_error(err + " '" + int_str + "'");
229+
}
230+
return parsed.value();
231+
}
232+
223233
static void MutateTxAddInput(CMutableTransaction& tx, const std::string& strInput)
224234
{
225235
std::vector<std::string> vStrInputParts = SplitString(strInput, ':');
@@ -245,8 +255,9 @@ static void MutateTxAddInput(CMutableTransaction& tx, const std::string& strInpu
245255

246256
// extract the optional sequence number
247257
uint32_t nSequenceIn = CTxIn::SEQUENCE_FINAL;
248-
if (vStrInputParts.size() > 2)
249-
nSequenceIn = std::stoul(vStrInputParts[2]);
258+
if (vStrInputParts.size() > 2) {
259+
nSequenceIn = TrimAndParse<uint32_t>(vStrInputParts.at(2), "invalid TX sequence id");
260+
}
250261

251262
// append to transaction input list
252263
CTxIn txin(txid, vout, CScript(), nSequenceIn);
@@ -324,10 +335,10 @@ static void MutateTxAddOutMultiSig(CMutableTransaction& tx, const std::string& s
324335
CAmount value = ExtractAndValidateValue(vStrInputParts[0]);
325336

326337
// Extract REQUIRED
327-
uint32_t required = stoul(vStrInputParts[1]);
338+
const uint32_t required{TrimAndParse<uint32_t>(vStrInputParts.at(1), "invalid multisig required number")};
328339

329340
// Extract NUMKEYS
330-
uint32_t numkeys = stoul(vStrInputParts[2]);
341+
const uint32_t numkeys{TrimAndParse<uint32_t>(vStrInputParts.at(2), "invalid multisig total number")};
331342

332343
// Validate there are the correct number of pubkeys
333344
if (vStrInputParts.size() < numkeys + 3)

test/util/data/bitcoin-util-test.json

+46-2
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,30 @@
425425
"output_cmp": "txcreatedata2.json",
426426
"description": "Creates a new transaction with one input, one address output and one data (zero value) output (output in json)"
427427
},
428+
{ "exec": "./dash-tx",
429+
"args":
430+
["-create",
431+
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0:11aa"],
432+
"return_code": 1,
433+
"error_txt": "error: invalid TX sequence id '11aa'",
434+
"description": "Try to parse a sequence number outside the allowed range"
435+
},
436+
{ "exec": "./dash-tx",
437+
"args":
438+
["-create",
439+
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0:-1"],
440+
"return_code": 1,
441+
"error_txt": "error: invalid TX sequence id '-1'",
442+
"description": "Try to parse a sequence number outside the allowed range"
443+
},
444+
{ "exec": "./dash-tx",
445+
"args":
446+
["-create",
447+
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0:4294967296"],
448+
"return_code": 1,
449+
"error_txt": "error: invalid TX sequence id '4294967296'",
450+
"description": "Try to parse a sequence number outside the allowed range"
451+
},
428452
{ "exec": "./dash-tx",
429453
"args":
430454
["-create",
@@ -433,6 +457,14 @@
433457
"output_cmp": "txcreatedata_seq0.hex",
434458
"description": "Creates a new transaction with one input with sequence number and one address output"
435459
},
460+
{ "exec": "./dash-tx",
461+
"args":
462+
["-create",
463+
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0: 4294967293 ",
464+
"outaddr=0.18:XijDvbYpPmznwgpWD3DkdYNfGmRP2KoVSk"],
465+
"output_cmp": "txcreatedata_seq0.hex",
466+
"description": "Creates a new transaction with one input with sequence number (+whitespace) and one address output"
467+
},
436468
{ "exec": "./dash-tx",
437469
"args":
438470
["-json",
@@ -457,15 +489,27 @@
457489
"output_cmp": "txcreatedata_seq1.json",
458490
"description": "Adds a new input with sequence number to a transaction (output in json)"
459491
},
492+
{ "exec": "./dash-tx",
493+
"args": ["-create", "outmultisig=1:-2:3:02a5:021:02df", "nversion=1"],
494+
"return_code": 1,
495+
"error_txt": "error: invalid multisig required number '-2'",
496+
"description": "Try to parse a multisig number outside the allowed range"
497+
},
498+
{ "exec": "./dash-tx",
499+
"args": ["-create", "outmultisig=1:2:3a:02a5:021:02df", "nversion=1"],
500+
"return_code": 1,
501+
"error_txt": "error: invalid multisig total number '3a'",
502+
"description": "Try to parse a multisig number outside the allowed range"
503+
},
460504
{ "exec": "./dash-tx",
461505
"args": ["-create", "outmultisig=1:2:3:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d:02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485", "nversion=1"],
462506
"output_cmp": "txcreatemultisig1.hex",
463507
"description": "Creates a new transaction with a single 2-of-3 multisig output"
464508
},
465509
{ "exec": "./dash-tx",
466-
"args": ["-json", "-create", "outmultisig=1:2:3:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d:02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485", "nversion=1"],
510+
"args": ["-json", "-create", "outmultisig=1: 2: 3:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d:02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485", "nversion=1"],
467511
"output_cmp": "txcreatemultisig1.json",
468-
"description": "Creates a new transaction with a single 2-of-3 multisig output (output in json)"
512+
"description": "Creates a new transaction with a single 2-of-3 multisig output (with whitespace, output in json)"
469513
},
470514
{ "exec": "./dash-tx",
471515
"args": ["-create", "outmultisig=1:2:3:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d:02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485:S", "nversion=1"],

0 commit comments

Comments
 (0)