LCOV - code coverage report
Current view: top level - src/util - moneystr.cpp (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 13 52 25.0 %
Date: 2023-11-10 23:46:46 Functions: 1 2 50.0 %
Branches: 12 58 20.7 %

           Branch data     Line data    Source code
       1                 :            : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2                 :            : // Copyright (c) 2009-2022 The Bitcoin Core developers
       3                 :            : // Distributed under the MIT software license, see the accompanying
       4                 :            : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       5                 :            : 
       6                 :            : #include <util/moneystr.h>
       7                 :            : 
       8                 :            : #include <consensus/amount.h>
       9                 :            : #include <tinyformat.h>
      10                 :            : #include <util/strencodings.h>
      11                 :            : #include <util/string.h>
      12                 :            : 
      13                 :            : #include <cstdint>
      14                 :            : #include <optional>
      15                 :            : 
      16                 :         17 : std::string FormatMoney(const CAmount n)
      17                 :            : {
      18                 :            :     // Note: not using straight sprintf here because we do NOT want
      19                 :            :     // localized number formatting.
      20                 :            :     static_assert(COIN > 1);
      21                 :         17 :     int64_t quotient = n / COIN;
      22                 :         17 :     int64_t remainder = n % COIN;
      23         [ +  - ]:         17 :     if (n < 0) {
      24                 :          0 :         quotient = -quotient;
      25                 :          0 :         remainder = -remainder;
      26                 :          0 :     }
      27                 :         17 :     std::string str = strprintf("%d.%08d", quotient, remainder);
      28                 :            : 
      29                 :            :     // Right-trim excess zeros before the decimal point:
      30                 :         17 :     int nTrim = 0;
      31 [ +  - ][ +  + ]:        193 :     for (int i = str.size()-1; (str[i] == '0' && IsDigit(str[i-2])); --i)
         [ +  - ][ +  - ]
                 [ +  + ]
      32                 :         83 :         ++nTrim;
      33         [ +  - ]:         17 :     if (nTrim)
      34         [ +  - ]:         17 :         str.erase(str.size()-nTrim, nTrim);
      35                 :            : 
      36         [ -  + ]:         17 :     if (n < 0)
      37         [ #  # ]:          0 :         str.insert(uint32_t{0}, 1, '-');
      38                 :         17 :     return str;
      39         [ +  - ]:         17 : }
      40                 :            : 
      41                 :            : 
      42                 :          0 : std::optional<CAmount> ParseMoney(const std::string& money_string)
      43                 :            : {
      44         [ #  # ]:          0 :     if (!ContainsNoNUL(money_string)) {
      45                 :          0 :         return std::nullopt;
      46                 :            :     }
      47                 :          0 :     const std::string str = TrimString(money_string);
      48         [ #  # ]:          0 :     if (str.empty()) {
      49                 :          0 :         return std::nullopt;
      50                 :            :     }
      51                 :            : 
      52                 :          0 :     std::string strWhole;
      53                 :          0 :     int64_t nUnits = 0;
      54                 :          0 :     const char* p = str.c_str();
      55         [ #  # ]:          0 :     for (; *p; p++)
      56                 :            :     {
      57         [ #  # ]:          0 :         if (*p == '.')
      58                 :            :         {
      59                 :          0 :             p++;
      60                 :          0 :             int64_t nMult = COIN / 10;
      61 [ #  # ][ #  # ]:          0 :             while (IsDigit(*p) && (nMult > 0))
                 [ #  # ]
      62                 :            :             {
      63                 :          0 :                 nUnits += nMult * (*p++ - '0');
      64                 :          0 :                 nMult /= 10;
      65                 :            :             }
      66                 :          0 :             break;
      67                 :            :         }
      68         [ #  # ]:          0 :         if (IsSpace(*p))
      69                 :          0 :             return std::nullopt;
      70 [ #  # ][ #  # ]:          0 :         if (!IsDigit(*p))
      71                 :          0 :             return std::nullopt;
      72         [ #  # ]:          0 :         strWhole.insert(strWhole.end(), *p);
      73                 :          0 :     }
      74         [ #  # ]:          0 :     if (*p) {
      75                 :          0 :         return std::nullopt;
      76                 :            :     }
      77         [ #  # ]:          0 :     if (strWhole.size() > 10) // guard against 63 bit overflow
      78                 :          0 :         return std::nullopt;
      79 [ #  # ][ #  # ]:          0 :     if (nUnits < 0 || nUnits > COIN)
      80                 :          0 :         return std::nullopt;
      81         [ #  # ]:          0 :     int64_t nWhole = LocaleIndependentAtoi<int64_t>(strWhole);
      82                 :          0 :     CAmount value = nWhole * COIN + nUnits;
      83                 :            : 
      84 [ #  # ][ #  # ]:          0 :     if (!MoneyRange(value)) {
      85                 :          0 :         return std::nullopt;
      86                 :            :     }
      87                 :            : 
      88                 :          0 :     return value;
      89                 :          0 : }

Generated by: LCOV version 1.14