LCOV - code coverage report
Current view: top level - src - utilstrencodings.h (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 36 36 100.0 %
Date: 2025-02-23 09:33:43 Functions: 26 26 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2014 The Bitcoin developers
       3             : // Copyright (c) 2017-2022 The PIVX Core developers
       4             : // Distributed under the MIT software license, see the accompanying
       5             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       6             : 
       7             : /**
       8             :  * Utilities for converting data from/to strings.
       9             :  */
      10             : #ifndef PIVX_UTILSTRENCODINGS_H
      11             : #define PIVX_UTILSTRENCODINGS_H
      12             : 
      13             : #include "support/allocators/secure.h"
      14             : #include "span.h"
      15             : 
      16             : #include <algorithm>
      17             : #include <iterator>
      18             : #include <stdint.h>
      19             : #include <string>
      20             : #include <vector>
      21             : 
      22             : #define BEGIN(a) ((char*)&(a))
      23             : #define END(a) ((char*)&((&(a))[1]))
      24             : #define UBEGIN(a) ((unsigned char*)&(a))
      25             : #define UEND(a) ((unsigned char*)&((&(a))[1]))
      26             : #define ARRAYLEN(array) (sizeof(array) / sizeof((array)[0]))
      27             : 
      28             : /** Used by SanitizeString() */
      29             : enum SafeChars
      30             : {
      31             :     SAFE_CHARS_DEFAULT, //!< The full set of allowed chars
      32             :     SAFE_CHARS_UA_COMMENT, //!< BIP-0014 subset
      33             :     SAFE_CHARS_FILENAME, //!< Chars allowed in filenames
      34             : };
      35             : 
      36             : /**
      37             : * Remove unsafe chars. Safe chars chosen to allow simple messages/URLs/email
      38             : * addresses, but avoid anything even possibly remotely dangerous like & or >
      39             : * @param[in] str    The string to sanitize
      40             : * @param[in] rule   The set of safe chars to choose (default: least restrictive)
      41             : * @return           A new string without unsafe chars
      42             : */
      43             : std::string SanitizeString(const std::string& str, int rule = SAFE_CHARS_DEFAULT);
      44             : 
      45             : /**
      46             : * Check URL format for conformance for validity to a defined pattern
      47             : * @param[in] strURL   The string to be processed for validity
      48             : * @param[in] strErr   A string that will be loaded with any validation error message
      49             : * @param[in] maxSize  An unsigned int, defaulted to 64, to restrict the length
      50             : * @return             A bool, true if valid, false if not (reason in strErr)
      51             : */
      52             : bool validateURL(const std::string& strURL, std::string& strErr, unsigned int maxSize = 64);
      53             : bool validateURL(const std::string& strURL);
      54             : 
      55             : std::vector<unsigned char> ParseHex(const char* psz);
      56             : std::vector<unsigned char> ParseHex(const std::string& str);
      57             : signed char HexDigit(char c);
      58             : bool IsHex(const std::string& str);
      59             : std::vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid = nullptr);
      60             : std::string DecodeBase64(const std::string& str);
      61             : std::string EncodeBase64(Span<const unsigned char> input);
      62             : std::string EncodeBase64(const std::string& str);
      63             : std::vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid = nullptr);
      64             : std::string DecodeBase32(const std::string& str);
      65             : 
      66             : /**
      67             :  * Base32 encode.
      68             :  * If `pad` is true, then the output will be padded with '=' so that its length
      69             :  * is a multiple of 8.
      70             :  */
      71             : std::string EncodeBase32(Span<const unsigned char> input, bool pad = true);
      72             : 
      73             : /**
      74             :  * Base32 encode.
      75             :  * If `pad` is true, then the output will be padded with '=' so that its length
      76             :  * is a multiple of 8.
      77             :  */
      78             : std::string EncodeBase32(const std::string& str, bool pad = true);
      79             : 
      80             : std::string i64tostr(int64_t n);
      81             : std::string itostr(int n);
      82             : int64_t atoi64(const char* psz);
      83             : int64_t atoi64(const std::string& str);
      84             : int atoi(const std::string& str);
      85             : 
      86             : /**
      87             :  * Tests if the given character is a decimal digit.
      88             :  * @param[in] c     character to test
      89             :  * @return          true if the argument is a decimal digit; otherwise false.
      90             :  */
      91       82603 : constexpr bool IsDigit(char c)
      92             : {
      93       82603 :     return c >= '0' && c <= '9';
      94             : }
      95             : 
      96             : /**
      97             :  * Convert string to signed 32-bit integer with strict parse error feedback.
      98             :  * @returns true if the entire string could be parsed as valid integer,
      99             :  *   false if not the entire string could be parsed or when overflow or underflow occurred.
     100             :  */
     101             : bool ParseInt32(const std::string& str, int32_t *out);
     102             : 
     103             : /**
     104             :  * Convert string to signed 64-bit integer with strict parse error feedback.
     105             :  * @returns true if the entire string could be parsed as valid integer,
     106             :  *   false if not the entire string could be parsed or when overflow or underflow occurred.
     107             :  */
     108             : bool ParseInt64(const std::string& str, int64_t *out);
     109             : 
     110             : /**
     111             :  * Convert decimal string to unsigned 8-bit integer with strict parse error feedback.
     112             :  * @returns true if the entire string could be parsed as valid integer,
     113             :  *   false if not the entire string could be parsed or when overflow or underflow occurred.
     114             :  */
     115             : bool ParseUInt8(const std::string& str, uint8_t *out);
     116             : 
     117             : /**
     118             :  * Convert decimal string to unsigned 32-bit integer with strict parse error feedback.
     119             :  * @returns true if the entire string could be parsed as valid integer,
     120             :  *   false if not the entire string could be parsed or when overflow or underflow occurred.
     121             :  */
     122             : bool ParseUInt32(const std::string& str, uint32_t *out);
     123             : 
     124             : /**
     125             :  * Convert string to double with strict parse error feedback.
     126             :  * @returns true if the entire string could be parsed as valid double,
     127             :  *   false if not the entire string could be parsed or when overflow or underflow occurred.
     128             :  */
     129             : bool ParseDouble(const std::string& str, double *out);
     130             : 
     131             : /* Return iterator to first non zero element, or itend */
     132             : template <typename T>
     133         382 : T FindFirstNonZero(T itbegin, T itend)
     134             : {
     135       49123 :     return std::find_if(itbegin, itend, [](unsigned char v) { return v != 0; });
     136             : }
     137             : 
     138             : /**
     139             :  * Convert a span of bytes to a lower-case hexadecimal string.
     140             :  */
     141             : std::string HexStr(const Span<const uint8_t> s);
     142      126408 : inline std::string HexStr(const Span<const char> s) { return HexStr(MakeUCharSpan(s)); }
     143             : 
     144             : /** Reverse the endianness of a string */
     145           9 : inline std::string ReverseEndianString(std::string in)
     146             : {
     147           9 :     std::string out = "";
     148           9 :     unsigned int s = in.size();
     149          67 :     for (unsigned int i = 0; i < s; i += 2) {
     150         116 :         out += in.substr(s - i - 2, 2);
     151             :     }
     152             : 
     153           9 :     return out;
     154             : }
     155             : 
     156             : /**
     157             :  * Format a paragraph of text to a fixed width, adding spaces for
     158             :  * indentation to any added line.
     159             :  */
     160             : std::string FormatParagraph(const std::string in, size_t width = 79, size_t indent = 0);
     161             : 
     162             : /**
     163             :  * Timing-attack-resistant comparison.
     164             :  * Takes time proportional to length
     165             :  * of first argument.
     166             :  */
     167             : template <typename T>
     168      298228 : bool TimingResistantEqual(const T& a, const T& b)
     169             : {
     170      298228 :     if (b.size() == 0) return a.size() == 0;
     171      298224 :     size_t accumulator = a.size() ^ b.size();
     172    22660328 :     for (size_t i = 0; i < a.size(); i++)
     173    22362118 :         accumulator |= a[i] ^ b[i % b.size()];
     174      298224 :     return accumulator == 0;
     175             : }
     176             : 
     177             : /**
     178             :   * Convert from one power-of-2 number base to another.
     179             :   *
     180             :   * Examples using ConvertBits<8, 5, true>():
     181             :   * 000000 -> 0000000000
     182             :   * 202020 -> 0400100200
     183             :   * 757575 -> 0e151a170a
     184             :   * abcdef -> 150f061e1e
     185             :   * ffffff -> 1f1f1f1f1e
     186             :   */
     187             : template<int frombits, int tobits, bool pad, typename O, typename I>
     188      327388 : bool ConvertBits(const O& outfn, I it, I end) {
     189      327388 :     size_t acc = 0;
     190      327388 :     size_t bits = 0;
     191      327388 :     constexpr size_t maxv = (1 << tobits) - 1;
     192      327388 :     constexpr size_t max_acc = (1 << (frombits + tobits - 1)) - 1;
     193    33075869 :     while (it != end) {
     194    32748465 :         acc = ((acc << frombits) | *it) & max_acc;
     195    32748465 :         bits += frombits;
     196    58341710 :         while (bits >= tobits) {
     197    25593240 :             bits -= tobits;
     198    25595335 :             outfn((acc >> bits) & maxv);
     199             :         }
     200    33074809 :         ++it;
     201             :     }
     202             :     if (pad) {
     203       19139 :         if (bits) outfn((acc << (tobits - bits)) & maxv);
     204      308249 :     } else if (bits >= frombits || ((acc << (tobits - bits)) & maxv)) {
     205           1 :         return false;
     206             :     }
     207             :     return true;
     208             : }
     209             : 
     210             : 
     211             : /** Parse number as fixed point according to JSON number syntax.
     212             :   * See http://json.org/number.gif
     213             :   * @returns true on success, false on error.
     214             :   * @note The result must be in the range (-10^18,10^18), otherwise an overflow error will trigger.
     215             :   */
     216             : bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out);
     217             : 
     218             : /**
     219             :  * Converts the given character to its lowercase equivalent.
     220             :  * This function is locale independent. It only converts uppercase
     221             :  * characters in the standard 7-bit ASCII range.
     222             :  * @param[in] c     the character to convert to lowercase.
     223             :  * @return          the lowercase equivalent of c; or the argument
     224             :  *                  if no conversion is possible.
     225             :  */
     226          70 : constexpr unsigned char ToLower(unsigned char c)
     227             : {
     228          70 :     return (c >= 'A' && c <= 'Z' ? (c - 'A') + 'a' : c);
     229             : }
     230             : 
     231             : /**
     232             :  * Returns the lowercase equivalent of the given string.
     233             :  * This function is locale independent. It only converts uppercase
     234             :  * characters in the standard 7-bit ASCII range.
     235             :  * This is a feature, not a limitation.
     236             :  *
     237             :  * @param[in] str   the string to convert to lowercase.
     238             :  * @returns         lowercased equivalent of str
     239             :  */
     240             : std::string ToLower(const std::string& str);
     241             : 
     242             : /**
     243             :  * Converts the given string to its lowercase equivalent.
     244             :  * This function is locale independent. It only converts uppercase
     245             :  * characters in the standard 7-bit ASCII range.
     246             :  * @param[in,out] str   the string to convert to lowercase.
     247             :  */
     248             : void Downcase(std::string& str);
     249             : 
     250             : /**
     251             :  * Converts the given character to its uppercase equivalent.
     252             :  * This function is locale independent. It only converts lowercase
     253             :  * characters in the standard 7-bit ASCII range.
     254             :  * @param[in] c     the character to convert to uppercase.
     255             :  * @return          the uppercase equivalent of c; or the argument
     256             :  *                  if no conversion is possible.
     257             :  */
     258          20 : constexpr unsigned char ToUpper(unsigned char c)
     259             : {
     260          20 :     return (c >= 'a' && c <= 'z' ? (c - 'a') + 'A' : c);
     261             : }
     262             : 
     263             : /**
     264             :  * Returns the uppercase equivalent of the given string.
     265             :  * This function is locale independent. It only converts lowercase
     266             :  * characters in the standard 7-bit ASCII range.
     267             :  * This is a feature, not a limitation.
     268             :  *
     269             :  * @param[in] str   the string to convert to uppercase.
     270             :  * @returns         UPPERCASED EQUIVALENT OF str
     271             :  */
     272             : std::string ToUpper(const std::string& str);
     273             : 
     274             : /**
     275             :  * Capitalizes the first character of the given string.
     276             :  * This function is locale independent. It only capitalizes the
     277             :  * first character of the argument if it has an uppercase equivalent
     278             :  * in the standard 7-bit ASCII range.
     279             :  * @param[in] str   the string to capitalize.
     280             :  * @return          string with the first letter capitalized.
     281             :  */
     282             : std::string Capitalize(std::string str);
     283             : 
     284             : /**
     285             :  * Checks for valid 4-byte UTF-8 encoding in a string
     286             :  * @param[in] str   the string to check.
     287             :  * @return          boolean. true for valid UTF-8 encoding.
     288             :  */
     289             : bool IsValidUTF8(const std::string& str);
     290             : 
     291             : #endif // PIVX_UTILSTRENCODINGS_H

Generated by: LCOV version 1.14