util: Fail to parse space-only strings in ParseMoney(...) (instead of parsing as zero)

This commit is contained in:
practicalswift 2020-03-05 20:20:36 +00:00
parent 727857d12d
commit 100213c5c2
2 changed files with 27 additions and 9 deletions

View File

@ -1182,6 +1182,12 @@ BOOST_AUTO_TEST_CASE(util_ParseMoney)
BOOST_CHECK_EQUAL(ret, COIN); BOOST_CHECK_EQUAL(ret, COIN);
BOOST_CHECK(ParseMoney("1", ret)); BOOST_CHECK(ParseMoney("1", ret));
BOOST_CHECK_EQUAL(ret, COIN); BOOST_CHECK_EQUAL(ret, COIN);
BOOST_CHECK(ParseMoney(" 1", ret));
BOOST_CHECK_EQUAL(ret, COIN);
BOOST_CHECK(ParseMoney("1 ", ret));
BOOST_CHECK_EQUAL(ret, COIN);
BOOST_CHECK(ParseMoney(" 1 ", ret));
BOOST_CHECK_EQUAL(ret, COIN);
BOOST_CHECK(ParseMoney("0.1", ret)); BOOST_CHECK(ParseMoney("0.1", ret));
BOOST_CHECK_EQUAL(ret, COIN/10); BOOST_CHECK_EQUAL(ret, COIN/10);
BOOST_CHECK(ParseMoney("0.01", ret)); BOOST_CHECK(ParseMoney("0.01", ret));
@ -1198,12 +1204,26 @@ BOOST_AUTO_TEST_CASE(util_ParseMoney)
BOOST_CHECK_EQUAL(ret, COIN/10000000); BOOST_CHECK_EQUAL(ret, COIN/10000000);
BOOST_CHECK(ParseMoney("0.00000001", ret)); BOOST_CHECK(ParseMoney("0.00000001", ret));
BOOST_CHECK_EQUAL(ret, COIN/100000000); BOOST_CHECK_EQUAL(ret, COIN/100000000);
BOOST_CHECK(ParseMoney(" 0.00000001 ", ret));
BOOST_CHECK_EQUAL(ret, COIN/100000000);
BOOST_CHECK(ParseMoney("0.00000001 ", ret));
BOOST_CHECK_EQUAL(ret, COIN/100000000);
BOOST_CHECK(ParseMoney(" 0.00000001", ret));
BOOST_CHECK_EQUAL(ret, COIN/100000000);
// Parsing amount that can not be represented in ret should fail // Parsing amount that can not be represented in ret should fail
BOOST_CHECK(!ParseMoney("0.000000001", ret)); BOOST_CHECK(!ParseMoney("0.000000001", ret));
// Parsing empty string should fail // Parsing empty string should fail
BOOST_CHECK(!ParseMoney("", ret)); BOOST_CHECK(!ParseMoney("", ret));
BOOST_CHECK(!ParseMoney(" ", ret));
BOOST_CHECK(!ParseMoney(" ", ret));
// Parsing two numbers should fail
BOOST_CHECK(!ParseMoney("1 2", ret));
BOOST_CHECK(!ParseMoney(" 1 2 ", ret));
BOOST_CHECK(!ParseMoney(" 1.2 3 ", ret));
BOOST_CHECK(!ParseMoney(" 1 2.3 ", ret));
// Attempted 63 bit overflow should fail // Attempted 63 bit overflow should fail
BOOST_CHECK(!ParseMoney("92233720368.54775808", ret)); BOOST_CHECK(!ParseMoney("92233720368.54775808", ret));

View File

@ -31,12 +31,12 @@ std::string FormatMoney(const CAmount& n)
} }
bool ParseMoney(const std::string& str, CAmount& nRet) bool ParseMoney(const std::string& money_string, CAmount& nRet)
{ {
if (!ValidAsCString(str)) { if (!ValidAsCString(money_string)) {
return false; return false;
} }
const std::string str = TrimString(money_string);
if (str.empty()) { if (str.empty()) {
return false; return false;
} }
@ -44,8 +44,6 @@ bool ParseMoney(const std::string& str, CAmount& nRet)
std::string strWhole; std::string strWhole;
int64_t nUnits = 0; int64_t nUnits = 0;
const char* p = str.c_str(); const char* p = str.c_str();
while (IsSpace(*p))
p++;
for (; *p; p++) for (; *p; p++)
{ {
if (*p == '.') if (*p == '.')
@ -60,14 +58,14 @@ bool ParseMoney(const std::string& str, CAmount& nRet)
break; break;
} }
if (IsSpace(*p)) if (IsSpace(*p))
break; return false;
if (!IsDigit(*p)) if (!IsDigit(*p))
return false; return false;
strWhole.insert(strWhole.end(), *p); strWhole.insert(strWhole.end(), *p);
} }
for (; *p; p++) if (*p) {
if (!IsSpace(*p)) return false;
return false; }
if (strWhole.size() > 10) // guard against 63 bit overflow if (strWhole.size() > 10) // guard against 63 bit overflow
return false; return false;
if (nUnits < 0 || nUnits > COIN) if (nUnits < 0 || nUnits > COIN)