Branch data Line data Source code
# 1 : : // Copyright 2014 BitPay Inc. # 2 : : // Copyright 2015 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 <stdint.h> # 7 : : #include <errno.h> # 8 : : #include <string.h> # 9 : : #include <stdlib.h> # 10 : : #include <stdexcept> # 11 : : #include <vector> # 12 : : #include <limits> # 13 : : #include <string> # 14 : : # 15 : : #include "univalue.h" # 16 : : # 17 : : namespace # 18 : : { # 19 : : static bool ParsePrechecks(const std::string& str) # 20 : 53829 : { # 21 [ - + ]: 53829 : if (str.empty()) // No empty string allowed # 22 : 0 : return false; # 23 [ + - ][ - + ]: 53829 : if (str.size() >= 1 && (json_isspace(str[0]) || json_isspace(str[str.size()-1]))) // No padding allowed # [ - + ] # 24 : 0 : return false; # 25 [ - + ]: 53829 : if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed # 26 : 0 : return false; # 27 : 53829 : return true; # 28 : 53829 : } # 29 : : # 30 : : bool ParseInt32(const std::string& str, int32_t *out) # 31 : 52240 : { # 32 [ - + ]: 52240 : if (!ParsePrechecks(str)) # 33 : 0 : return false; # 34 : 52240 : char *endp = NULL; # 35 : 52240 : errno = 0; // strtol will not set errno if valid # 36 : 52240 : long int n = strtol(str.c_str(), &endp, 10); # 37 [ + - ]: 52240 : if(out) *out = (int32_t)n; # 38 : : // Note that strtol returns a *long int*, so even if strtol doesn't report an over/underflow # 39 : : // we still have to check that the returned value is within the range of an *int32_t*. On 64-bit # 40 : : // platforms the size of these types may be different. # 41 [ + - ][ + - ]: 52240 : return endp && *endp == 0 && !errno && # [ + - ] # 42 [ + - ]: 52240 : n >= std::numeric_limits<int32_t>::min() && # 43 [ + - ]: 52240 : n <= std::numeric_limits<int32_t>::max(); # 44 : 52240 : } # 45 : : # 46 : : bool ParseInt64(const std::string& str, int64_t *out) # 47 : 1581 : { # 48 [ - + ]: 1581 : if (!ParsePrechecks(str)) # 49 : 0 : return false; # 50 : 1581 : char *endp = NULL; # 51 : 1581 : errno = 0; // strtoll will not set errno if valid # 52 : 1581 : long long int n = strtoll(str.c_str(), &endp, 10); # 53 [ + - ]: 1581 : if(out) *out = (int64_t)n; # 54 : : // Note that strtoll returns a *long long int*, so even if strtol doesn't report a over/underflow # 55 : : // we still have to check that the returned value is within the range of an *int64_t*. # 56 [ + - ][ + - ]: 1581 : return endp && *endp == 0 && !errno && # [ + - ] # 57 [ + - ]: 1581 : n >= std::numeric_limits<int64_t>::min() && # 58 [ + - ]: 1581 : n <= std::numeric_limits<int64_t>::max(); # 59 : 1581 : } # 60 : : # 61 : : bool ParseDouble(const std::string& str, double *out) # 62 : 8 : { # 63 [ - + ]: 8 : if (!ParsePrechecks(str)) # 64 : 0 : return false; # 65 [ + + ][ - + ]: 8 : if (str.size() >= 2 && str[0] == '0' && str[1] == 'x') // No hexadecimal floats allowed # [ # # ] # 66 : 0 : return false; # 67 : 8 : std::istringstream text(str); # 68 : 8 : text.imbue(std::locale::classic()); # 69 : 8 : double result; # 70 : 8 : text >> result; # 71 [ + - ]: 8 : if(out) *out = result; # 72 [ + - ][ + - ]: 8 : return text.eof() && !text.fail(); # 73 : 8 : } # 74 : : } # 75 : : # 76 : : const std::vector<std::string>& UniValue::getKeys() const # 77 : 57298 : { # 78 [ - + ]: 57298 : if (typ != VOBJ) # 79 : 0 : throw std::runtime_error("JSON value is not an object as expected"); # 80 : 57298 : return keys; # 81 : 57298 : } # 82 : : # 83 : : const std::vector<UniValue>& UniValue::getValues() const # 84 : 55386 : { # 85 [ + + ][ - + ]: 55386 : if (typ != VOBJ && typ != VARR) # 86 : 0 : throw std::runtime_error("JSON value is not an object or array as expected"); # 87 : 55386 : return values; # 88 : 55386 : } # 89 : : # 90 : : bool UniValue::get_bool() const # 91 : 4675 : { # 92 [ + + ]: 4675 : if (typ != VBOOL) # 93 : 7 : throw std::runtime_error("JSON value is not a boolean as expected"); # 94 : 4668 : return getBool(); # 95 : 4668 : } # 96 : : # 97 : : const std::string& UniValue::get_str() const # 98 : 454124 : { # 99 [ + + ]: 454124 : if (typ != VSTR) # 100 : 12 : throw std::runtime_error("JSON value is not a string as expected"); # 101 : 454112 : return getValStr(); # 102 : 454112 : } # 103 : : # 104 : : int UniValue::get_int() const # 105 : 52244 : { # 106 [ + + ]: 52244 : if (typ != VNUM) # 107 : 4 : throw std::runtime_error("JSON value is not an integer as expected"); # 108 : 52240 : int32_t retval; # 109 [ - + ]: 52240 : if (!ParseInt32(getValStr(), &retval)) # 110 : 0 : throw std::runtime_error("JSON integer out of range"); # 111 : 52240 : return retval; # 112 : 52240 : } # 113 : : # 114 : : int64_t UniValue::get_int64() const # 115 : 1582 : { # 116 [ + + ]: 1582 : if (typ != VNUM) # 117 : 1 : throw std::runtime_error("JSON value is not an integer as expected"); # 118 : 1581 : int64_t retval; # 119 [ - + ]: 1581 : if (!ParseInt64(getValStr(), &retval)) # 120 : 0 : throw std::runtime_error("JSON integer out of range"); # 121 : 1581 : return retval; # 122 : 1581 : } # 123 : : # 124 : : double UniValue::get_real() const # 125 : 9 : { # 126 [ + + ]: 9 : if (typ != VNUM) # 127 : 1 : throw std::runtime_error("JSON value is not a number as expected"); # 128 : 8 : double retval; # 129 [ - + ]: 8 : if (!ParseDouble(getValStr(), &retval)) # 130 : 0 : throw std::runtime_error("JSON double out of range"); # 131 : 8 : return retval; # 132 : 8 : } # 133 : : # 134 : : const UniValue& UniValue::get_obj() const # 135 : 121111 : { # 136 [ + + ]: 121111 : if (typ != VOBJ) # 137 : 2 : throw std::runtime_error("JSON value is not an object as expected"); # 138 : 121109 : return *this; # 139 : 121109 : } # 140 : : # 141 : : const UniValue& UniValue::get_array() const # 142 : 6994 : { # 143 [ + + ]: 6994 : if (typ != VARR) # 144 : 2 : throw std::runtime_error("JSON value is not an array as expected"); # 145 : 6992 : return *this; # 146 : 6992 : } # 147 : :