mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 20:12:57 +01:00
Merge #13603: bitcoin-tx: Stricter check for valid integers
57889e688dd0987a1e087cd48d216a413127601e bitcoin-tx: Stricter check for valid integers (Daniel Kraft) Pull request description: Just calling `atoi` to convert strings to integers does not check for valid integers very thoroughly; in particular, it just ignores everything starting from the first non-numeral character. Even a string like "foo" is fine and silently returns 0. This meant that `bitcoin-tx` would not fail if such a string was passed in various places where an integer is expected (like the `locktime` or an input/output index); this means that it would, for instance, silently accept a typo and interpret it in an unexpected way. In this change, we use `ParseInt64` for parsing strings to integers, which actually verifies that the full string is valid as number. New tests in the `bitcoin-util-test` cover the new error paths. This fixes #13599. Tree-SHA512: 146a0af275e9f57784e5d0582d3defbac35551b54b6b7232f8a0b20db04aa611125e52aa4512ef2f8ed2cafc2a12fe586f9d10ed66d641cff090288f279b1988
This commit is contained in:
parent
16591be580
commit
44c7301288
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2009-2015 The Bitcoin Core developers
|
// Copyright (c) 2009-2018 The Bitcoin Core developers
|
||||||
// Distributed under the MIT software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
@ -190,18 +190,18 @@ static CAmount ExtractAndValidateValue(const std::string& strValue)
|
|||||||
|
|
||||||
static void MutateTxVersion(CMutableTransaction& tx, const std::string& cmdVal)
|
static void MutateTxVersion(CMutableTransaction& tx, const std::string& cmdVal)
|
||||||
{
|
{
|
||||||
int64_t newVersion = atoi64(cmdVal);
|
int64_t newVersion;
|
||||||
if (newVersion < 1 || newVersion > CTransaction::MAX_STANDARD_VERSION)
|
if (!ParseInt64(cmdVal, &newVersion) || newVersion < 1 || newVersion > CTransaction::MAX_STANDARD_VERSION)
|
||||||
throw std::runtime_error("Invalid TX version requested");
|
throw std::runtime_error("Invalid TX version requested: '" + cmdVal + "'");
|
||||||
|
|
||||||
tx.nVersion = (int) newVersion;
|
tx.nVersion = (int) newVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MutateTxLocktime(CMutableTransaction& tx, const std::string& cmdVal)
|
static void MutateTxLocktime(CMutableTransaction& tx, const std::string& cmdVal)
|
||||||
{
|
{
|
||||||
int64_t newLocktime = atoi64(cmdVal);
|
int64_t newLocktime;
|
||||||
if (newLocktime < 0LL || newLocktime > 0xffffffffLL)
|
if (!ParseInt64(cmdVal, &newLocktime) || newLocktime < 0LL || newLocktime > 0xffffffffLL)
|
||||||
throw std::runtime_error("Invalid TX locktime requested");
|
throw std::runtime_error("Invalid TX locktime requested: '" + cmdVal + "'");
|
||||||
|
|
||||||
tx.nLockTime = (unsigned int) newLocktime;
|
tx.nLockTime = (unsigned int) newLocktime;
|
||||||
}
|
}
|
||||||
@ -225,10 +225,10 @@ static void MutateTxAddInput(CMutableTransaction& tx, const std::string& strInpu
|
|||||||
static const unsigned int maxVout = MaxBlockSize() / minTxOutSz;
|
static const unsigned int maxVout = MaxBlockSize() / minTxOutSz;
|
||||||
|
|
||||||
// extract and validate vout
|
// extract and validate vout
|
||||||
std::string strVout = vStrInputParts[1];
|
const std::string& strVout = vStrInputParts[1];
|
||||||
int vout = atoi(strVout);
|
int64_t vout;
|
||||||
if ((vout < 0) || (vout > (int)maxVout))
|
if (!ParseInt64(strVout, &vout) || vout < 0 || vout > static_cast<int64_t>(maxVout))
|
||||||
throw std::runtime_error("invalid TX input vout");
|
throw std::runtime_error("invalid TX input vout '" + strVout + "'");
|
||||||
|
|
||||||
// extract the optional sequence number
|
// extract the optional sequence number
|
||||||
uint32_t nSequenceIn=std::numeric_limits<unsigned int>::max();
|
uint32_t nSequenceIn=std::numeric_limits<unsigned int>::max();
|
||||||
@ -433,10 +433,9 @@ static void MutateTxAddOutScript(CMutableTransaction& tx, const std::string& str
|
|||||||
static void MutateTxDelInput(CMutableTransaction& tx, const std::string& strInIdx)
|
static void MutateTxDelInput(CMutableTransaction& tx, const std::string& strInIdx)
|
||||||
{
|
{
|
||||||
// parse requested deletion index
|
// parse requested deletion index
|
||||||
int inIdx = atoi(strInIdx);
|
int64_t inIdx;
|
||||||
if (inIdx < 0 || inIdx >= (int)tx.vin.size()) {
|
if (!ParseInt64(strInIdx, &inIdx) || inIdx < 0 || inIdx >= static_cast<int64_t>(tx.vin.size())) {
|
||||||
std::string strErr = "Invalid TX input index '" + strInIdx + "'";
|
throw std::runtime_error("Invalid TX input index '" + strInIdx + "'");
|
||||||
throw std::runtime_error(strErr.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete input from transaction
|
// delete input from transaction
|
||||||
@ -446,10 +445,9 @@ static void MutateTxDelInput(CMutableTransaction& tx, const std::string& strInId
|
|||||||
static void MutateTxDelOutput(CMutableTransaction& tx, const std::string& strOutIdx)
|
static void MutateTxDelOutput(CMutableTransaction& tx, const std::string& strOutIdx)
|
||||||
{
|
{
|
||||||
// parse requested deletion index
|
// parse requested deletion index
|
||||||
int outIdx = atoi(strOutIdx);
|
int64_t outIdx;
|
||||||
if (outIdx < 0 || outIdx >= (int)tx.vout.size()) {
|
if (!ParseInt64(strOutIdx, &outIdx) || outIdx < 0 || outIdx >= static_cast<int64_t>(tx.vout.size())) {
|
||||||
std::string strErr = "Invalid TX output index '" + strOutIdx + "'";
|
throw std::runtime_error("Invalid TX output index '" + strOutIdx + "'");
|
||||||
throw std::runtime_error(strErr.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete output from transaction
|
// delete output from transaction
|
||||||
@ -547,7 +545,7 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)
|
|||||||
|
|
||||||
uint256 txid = ParseHashStr(prevOut["txid"].get_str(), "txid");
|
uint256 txid = ParseHashStr(prevOut["txid"].get_str(), "txid");
|
||||||
|
|
||||||
int nOut = atoi(prevOut["vout"].getValStr());
|
const int nOut = prevOut["vout"].get_int();
|
||||||
if (nOut < 0)
|
if (nOut < 0)
|
||||||
throw std::runtime_error("vout must be positive");
|
throw std::runtime_error("vout must be positive");
|
||||||
|
|
||||||
|
@ -26,6 +26,12 @@
|
|||||||
"output_cmp": "blanktxv2.json",
|
"output_cmp": "blanktxv2.json",
|
||||||
"description": "Creates a blank transaction when nothing is piped into dash-tx (output in json)"
|
"description": "Creates a blank transaction when nothing is piped into dash-tx (output in json)"
|
||||||
},
|
},
|
||||||
|
{ "exec": "./dash-tx",
|
||||||
|
"args": ["-create", "nversion=1foo"],
|
||||||
|
"return_code": 1,
|
||||||
|
"error_txt": "error: Invalid TX version requested",
|
||||||
|
"description": "Tests the check for invalid nversion value"
|
||||||
|
},
|
||||||
{ "exec": "./dash-tx",
|
{ "exec": "./dash-tx",
|
||||||
"args": ["-", "delin=1"],
|
"args": ["-", "delin=1"],
|
||||||
"input": "tx394b54bb.hex",
|
"input": "tx394b54bb.hex",
|
||||||
@ -45,6 +51,13 @@
|
|||||||
"error_txt": "error: Invalid TX input index '31'",
|
"error_txt": "error: Invalid TX input index '31'",
|
||||||
"description": "Attempts to delete an input with a bad index from a transaction. Expected to fail."
|
"description": "Attempts to delete an input with a bad index from a transaction. Expected to fail."
|
||||||
},
|
},
|
||||||
|
{ "exec": "./dash-tx",
|
||||||
|
"args": ["-", "delin=1foo"],
|
||||||
|
"input": "tx394b54bb.hex",
|
||||||
|
"return_code": 1,
|
||||||
|
"error_txt": "error: Invalid TX input index",
|
||||||
|
"description": "Tests the check for an invalid input index with delin"
|
||||||
|
},
|
||||||
{ "exec": "./dash-tx",
|
{ "exec": "./dash-tx",
|
||||||
"args": ["-", "delout=1"],
|
"args": ["-", "delout=1"],
|
||||||
"input": "tx394b54bb.hex",
|
"input": "tx394b54bb.hex",
|
||||||
@ -64,6 +77,13 @@
|
|||||||
"error_txt": "error: Invalid TX output index '2'",
|
"error_txt": "error: Invalid TX output index '2'",
|
||||||
"description": "Attempts to delete an output with a bad index from a transaction. Expected to fail."
|
"description": "Attempts to delete an output with a bad index from a transaction. Expected to fail."
|
||||||
},
|
},
|
||||||
|
{ "exec": "./dash-tx",
|
||||||
|
"args": ["-", "delout=1foo"],
|
||||||
|
"input": "tx394b54bb.hex",
|
||||||
|
"return_code": 1,
|
||||||
|
"error_txt": "error: Invalid TX output index",
|
||||||
|
"description": "Tests the check for an invalid output index with delout"
|
||||||
|
},
|
||||||
{ "exec": "./dash-tx",
|
{ "exec": "./dash-tx",
|
||||||
"args": ["-", "locktime=317000"],
|
"args": ["-", "locktime=317000"],
|
||||||
"input": "tx394b54bb.hex",
|
"input": "tx394b54bb.hex",
|
||||||
@ -76,6 +96,29 @@
|
|||||||
"output_cmp": "tt-locktime317000-out.json",
|
"output_cmp": "tt-locktime317000-out.json",
|
||||||
"description": "Adds an nlocktime to a transaction (output in json)"
|
"description": "Adds an nlocktime to a transaction (output in json)"
|
||||||
},
|
},
|
||||||
|
{ "exec": "./dash-tx",
|
||||||
|
"args": ["-create", "locktime=317000foo"],
|
||||||
|
"return_code": 1,
|
||||||
|
"error_txt": "error: Invalid TX locktime requested",
|
||||||
|
"description": "Tests the check for invalid locktime value"
|
||||||
|
},
|
||||||
|
{ "exec": "./dash-tx",
|
||||||
|
"args":
|
||||||
|
["-create",
|
||||||
|
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0",
|
||||||
|
"replaceable=0foo"],
|
||||||
|
"return_code": 1,
|
||||||
|
"error_txt": "error: Invalid TX input index",
|
||||||
|
"description": "Tests the check for an invalid input index with replaceable"
|
||||||
|
},
|
||||||
|
{ "exec": "./dash-tx",
|
||||||
|
"args":
|
||||||
|
["-create",
|
||||||
|
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0x"],
|
||||||
|
"return_code": 1,
|
||||||
|
"error_txt": "error: invalid TX input vout",
|
||||||
|
"description": "Tests the check for an invalid vout value when adding an input"
|
||||||
|
},
|
||||||
{ "exec": "./dash-tx",
|
{ "exec": "./dash-tx",
|
||||||
"args":
|
"args":
|
||||||
["-create",
|
["-create",
|
||||||
@ -205,6 +248,18 @@
|
|||||||
"output_cmp": "txcreatesignv2.hex",
|
"output_cmp": "txcreatesignv2.hex",
|
||||||
"description": "Creates a new transaction with a single input and a single output, and then signs the transaction"
|
"description": "Creates a new transaction with a single input and a single output, and then signs the transaction"
|
||||||
},
|
},
|
||||||
|
{ "exec": "./dash-tx",
|
||||||
|
"args":
|
||||||
|
["-create",
|
||||||
|
"in=4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485:0",
|
||||||
|
"set=privatekeys:[\"5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf\"]",
|
||||||
|
"set=prevtxs:[{\"txid\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\",\"vout\":\"0foo\",\"scriptPubKey\":\"76a91491b24bf9f5288532960ac687abb035127b1d28a588ac\"}]",
|
||||||
|
"sign=ALL",
|
||||||
|
"outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"],
|
||||||
|
"return_code": 1,
|
||||||
|
"error_txt": "error: prevtxs internal object typecheck fail",
|
||||||
|
"description": "Tests the check for invalid vout index in prevtxs for sign"
|
||||||
|
},
|
||||||
{ "exec": "./dash-tx",
|
{ "exec": "./dash-tx",
|
||||||
"args":
|
"args":
|
||||||
["-create", "outpubkey=0:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397", "nversion=1"],
|
["-create", "outpubkey=0:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397", "nversion=1"],
|
||||||
|
Loading…
Reference in New Issue
Block a user