diff options
| author | Bitflash <admin@bitflash.network> | 2026-08-11 11:04:03 -0300 |
|---|---|---|
| committer | Bitflash <admin@bitflash.network> | 2026-08-11 11:04:03 -0300 |
| commit | a83fae37099cb102beb5a4c174a4abe6ef3f24a4 (patch) | |
| tree | e2ec970053c813bcb330f0913953f030ecc6d19e /src/util.cpp | |
| parent | 3442c1c7f4b0476840b4ab3fab244eb000be0d04 (diff) | |
| parent | faf6c4d24304b770c2d43515da04832b2124c92a (diff) | |
Merge pull request 'money: ParseMoney accepts full 8 decimals' (#23) from parsemoney-full-decimals into main
Diffstat (limited to 'src/util.cpp')
| -rw-r--r-- | src/util.cpp | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/src/util.cpp b/src/util.cpp index d52ca88..0cd0133 100644 --- a/src/util.cpp +++ b/src/util.cpp | |||
| @@ -337,7 +337,7 @@ string FormatMoney(int64 n, bool fPlus) | |||
| 337 | bool ParseMoney(const char* pszIn, int64& nRet) | 337 | bool ParseMoney(const char* pszIn, int64& nRet) |
| 338 | { | 338 | { |
| 339 | string strWhole; | 339 | string strWhole; |
| 340 | int64 nCents = 0; | 340 | int64 nUnits = 0; // fractional part, scaled to COIN (8 decimals) |
| 341 | const char* p = pszIn; | 341 | const char* p = pszIn; |
| 342 | while (isspace(*p)) | 342 | while (isspace(*p)) |
| 343 | p++; | 343 | p++; |
| @@ -348,12 +348,16 @@ bool ParseMoney(const char* pszIn, int64& nRet) | |||
| 348 | if (*p == '.') | 348 | if (*p == '.') |
| 349 | { | 349 | { |
| 350 | p++; | 350 | p++; |
| 351 | if (!isdigit(p[0]) || !isdigit(p[1])) | 351 | int64 nMult = COIN / 10; // weight of the first decimal digit |
| 352 | while (isdigit(*p) && nMult > 0) | ||
| 353 | { | ||
| 354 | nUnits += nMult * (*p - '0'); | ||
| 355 | nMult /= 10; | ||
| 356 | p++; | ||
| 357 | } | ||
| 358 | // reject more than 8 fractional digits rather than silently truncate | ||
| 359 | if (isdigit(*p)) | ||
| 352 | return false; | 360 | return false; |
| 353 | nCents = atoi64(p); | ||
| 354 | if (nCents < 0 || nCents > 99) | ||
| 355 | return false; | ||
| 356 | p += 2; | ||
| 357 | break; | 361 | break; |
| 358 | } | 362 | } |
| 359 | if (isspace(*p)) | 363 | if (isspace(*p)) |
| @@ -365,13 +369,12 @@ bool ParseMoney(const char* pszIn, int64& nRet) | |||
| 365 | for (; *p; p++) | 369 | for (; *p; p++) |
| 366 | if (!isspace(*p)) | 370 | if (!isspace(*p)) |
| 367 | return false; | 371 | return false; |
| 368 | if (strWhole.size() > 17) | 372 | if (strWhole.size() > 10) // 10 whole digits * COIN stays within int64 |
| 369 | return false; | 373 | return false; |
| 370 | int64 nWhole = atoi64(strWhole); | 374 | int64 nWhole = atoi64(strWhole); |
| 371 | int64 nValue = nWhole * 100 + nCents; | 375 | int64 nValue = nWhole * COIN + nUnits; |
| 372 | if (nValue / 100 != nWhole) | 376 | if (nValue < 0 || (nValue - nUnits) / COIN != nWhole) |
| 373 | return false; | 377 | return false; |
| 374 | nValue *= CENT; | ||
| 375 | nRet = nValue; | 378 | nRet = nValue; |
| 376 | return true; | 379 | return true; |
| 377 | } | 380 | } |