Skip to content

Commit 0dc6218

Browse files
author
MarcoFalke
committed
Merge #18270: util: Fail to parse whitespace-only strings in ParseMoney(...) (instead of parsing as zero)
100213c util: Fail to parse space-only strings in ParseMoney(...) (instead of parsing as zero) (practicalswift) Pull request description: Fail to parse whitespace-only strings in `ParseMoney(...)` (instead of parsing as `0`). This is a follow-up to #18225 ("util: Fail to parse empty string in `ParseMoney`") which made `ParseMoney("")` fail instead of parsing as `0`. Context: bitcoin/bitcoin#18225 (comment) Current non-test call sites: ``` $ git grep ParseMoney ":(exclude)src/test/" src/bitcoin-tx.cpp: if (!ParseMoney(strValue, value)) src/init.cpp: if (!ParseMoney(gArgs.GetArg("-incrementalrelayfee", ""), n)) src/init.cpp: if (!ParseMoney(gArgs.GetArg("-minrelaytxfee", ""), n)) { src/init.cpp: if (!ParseMoney(gArgs.GetArg("-blockmintxfee", ""), n)) src/init.cpp: if (!ParseMoney(gArgs.GetArg("-dustrelayfee", ""), n)) src/miner.cpp: if (gArgs.IsArgSet("-blockmintxfee") && ParseMoney(gArgs.GetArg("-blockmintxfee", ""), n)) { src/util/moneystr.cpp:bool ParseMoney(const std::string& str, CAmount& nRet) src/util/moneystr.h:NODISCARD bool ParseMoney(const std::string& str, CAmount& nRet); src/wallet/wallet.cpp: if (!ParseMoney(gArgs.GetArg("-mintxfee", ""), n) || 0 == n) { src/wallet/wallet.cpp: if (!ParseMoney(gArgs.GetArg("-fallbackfee", ""), nFeePerK)) { src/wallet/wallet.cpp: if (!ParseMoney(gArgs.GetArg("-discardfee", ""), nFeePerK)) { src/wallet/wallet.cpp: if (!ParseMoney(gArgs.GetArg("-paytxfee", ""), nFeePerK)) { src/wallet/wallet.cpp: if (!ParseMoney(gArgs.GetArg("-maxtxfee", ""), nMaxFee)) { ``` ACKs for top commit: Empact: ACK bitcoin/bitcoin@100213c sipa: ACK 100213c theStack: ACK bitcoin/bitcoin@100213c Tree-SHA512: cadfb1ac8276cf54736c3444705f2650e7a08023673aedc729fabe751ae80f6c490fc0945ee38dbfd02c95e4d9853d1e4c84f5d3c310f44eaf3585afec8a4c22
2 parents 7f9dedb + 100213c commit 0dc6218

File tree

2 files changed

+27
-9
lines changed

2 files changed

+27
-9
lines changed

src/test/util_tests.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,6 +1182,12 @@ BOOST_AUTO_TEST_CASE(util_ParseMoney)
11821182
BOOST_CHECK_EQUAL(ret, COIN);
11831183
BOOST_CHECK(ParseMoney("1", ret));
11841184
BOOST_CHECK_EQUAL(ret, COIN);
1185+
BOOST_CHECK(ParseMoney(" 1", ret));
1186+
BOOST_CHECK_EQUAL(ret, COIN);
1187+
BOOST_CHECK(ParseMoney("1 ", ret));
1188+
BOOST_CHECK_EQUAL(ret, COIN);
1189+
BOOST_CHECK(ParseMoney(" 1 ", ret));
1190+
BOOST_CHECK_EQUAL(ret, COIN);
11851191
BOOST_CHECK(ParseMoney("0.1", ret));
11861192
BOOST_CHECK_EQUAL(ret, COIN/10);
11871193
BOOST_CHECK(ParseMoney("0.01", ret));
@@ -1198,12 +1204,26 @@ BOOST_AUTO_TEST_CASE(util_ParseMoney)
11981204
BOOST_CHECK_EQUAL(ret, COIN/10000000);
11991205
BOOST_CHECK(ParseMoney("0.00000001", ret));
12001206
BOOST_CHECK_EQUAL(ret, COIN/100000000);
1207+
BOOST_CHECK(ParseMoney(" 0.00000001 ", ret));
1208+
BOOST_CHECK_EQUAL(ret, COIN/100000000);
1209+
BOOST_CHECK(ParseMoney("0.00000001 ", ret));
1210+
BOOST_CHECK_EQUAL(ret, COIN/100000000);
1211+
BOOST_CHECK(ParseMoney(" 0.00000001", ret));
1212+
BOOST_CHECK_EQUAL(ret, COIN/100000000);
12011213

12021214
// Parsing amount that can not be represented in ret should fail
12031215
BOOST_CHECK(!ParseMoney("0.000000001", ret));
12041216

12051217
// Parsing empty string should fail
12061218
BOOST_CHECK(!ParseMoney("", ret));
1219+
BOOST_CHECK(!ParseMoney(" ", ret));
1220+
BOOST_CHECK(!ParseMoney(" ", ret));
1221+
1222+
// Parsing two numbers should fail
1223+
BOOST_CHECK(!ParseMoney("1 2", ret));
1224+
BOOST_CHECK(!ParseMoney(" 1 2 ", ret));
1225+
BOOST_CHECK(!ParseMoney(" 1.2 3 ", ret));
1226+
BOOST_CHECK(!ParseMoney(" 1 2.3 ", ret));
12071227

12081228
// Attempted 63 bit overflow should fail
12091229
BOOST_CHECK(!ParseMoney("92233720368.54775808", ret));

src/util/moneystr.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,19 @@ std::string FormatMoney(const CAmount& n)
3131
}
3232

3333

34-
bool ParseMoney(const std::string& str, CAmount& nRet)
34+
bool ParseMoney(const std::string& money_string, CAmount& nRet)
3535
{
36-
if (!ValidAsCString(str)) {
36+
if (!ValidAsCString(money_string)) {
3737
return false;
3838
}
39-
39+
const std::string str = TrimString(money_string);
4040
if (str.empty()) {
4141
return false;
4242
}
4343

4444
std::string strWhole;
4545
int64_t nUnits = 0;
4646
const char* p = str.c_str();
47-
while (IsSpace(*p))
48-
p++;
4947
for (; *p; p++)
5048
{
5149
if (*p == '.')
@@ -60,14 +58,14 @@ bool ParseMoney(const std::string& str, CAmount& nRet)
6058
break;
6159
}
6260
if (IsSpace(*p))
63-
break;
61+
return false;
6462
if (!IsDigit(*p))
6563
return false;
6664
strWhole.insert(strWhole.end(), *p);
6765
}
68-
for (; *p; p++)
69-
if (!IsSpace(*p))
70-
return false;
66+
if (*p) {
67+
return false;
68+
}
7169
if (strWhole.size() > 10) // guard against 63 bit overflow
7270
return false;
7371
if (nUnits < 0 || nUnits > COIN)

0 commit comments

Comments
 (0)