Bitcoin Core 22.99.0
P2P Digital Currency
univalue_get.cpp
Go to the documentation of this file.
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 https://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#include <sstream>
15
16#include "univalue.h"
17
18namespace
19{
20static bool ParsePrechecks(const std::string& str)
21{
22 if (str.empty()) // No empty string allowed
23 return false;
24 if (str.size() >= 1 && (json_isspace(str[0]) || json_isspace(str[str.size()-1]))) // No padding allowed
25 return false;
26 if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed
27 return false;
28 return true;
29}
30
31bool ParseInt32(const std::string& str, int32_t *out)
32{
33 if (!ParsePrechecks(str))
34 return false;
35 char *endp = nullptr;
36 errno = 0; // strtol will not set errno if valid
37 long int n = strtol(str.c_str(), &endp, 10);
38 if(out) *out = (int32_t)n;
39 // Note that strtol returns a *long int*, so even if strtol doesn't report an over/underflow
40 // we still have to check that the returned value is within the range of an *int32_t*. On 64-bit
41 // platforms the size of these types may be different.
42 return endp && *endp == 0 && !errno &&
43 n >= std::numeric_limits<int32_t>::min() &&
44 n <= std::numeric_limits<int32_t>::max();
45}
46
47bool ParseInt64(const std::string& str, int64_t *out)
48{
49 if (!ParsePrechecks(str))
50 return false;
51 char *endp = nullptr;
52 errno = 0; // strtoll will not set errno if valid
53 long long int n = strtoll(str.c_str(), &endp, 10);
54 if(out) *out = (int64_t)n;
55 // Note that strtoll returns a *long long int*, so even if strtol doesn't report a over/underflow
56 // we still have to check that the returned value is within the range of an *int64_t*.
57 return endp && *endp == 0 && !errno &&
58 n >= std::numeric_limits<int64_t>::min() &&
59 n <= std::numeric_limits<int64_t>::max();
60}
61
62bool ParseDouble(const std::string& str, double *out)
63{
64 if (!ParsePrechecks(str))
65 return false;
66 if (str.size() >= 2 && str[0] == '0' && str[1] == 'x') // No hexadecimal floats allowed
67 return false;
68 std::istringstream text(str);
69 text.imbue(std::locale::classic());
70 double result;
71 text >> result;
72 if(out) *out = result;
73 return text.eof() && !text.fail();
74}
75}
76
77const std::vector<std::string>& UniValue::getKeys() const
78{
79 if (typ != VOBJ)
80 throw std::runtime_error("JSON value is not an object as expected");
81 return keys;
82}
83
84const std::vector<UniValue>& UniValue::getValues() const
85{
86 if (typ != VOBJ && typ != VARR)
87 throw std::runtime_error("JSON value is not an object or array as expected");
88 return values;
89}
90
92{
93 if (typ != VBOOL)
94 throw std::runtime_error("JSON value is not a boolean as expected");
95 return getBool();
96}
97
98const std::string& UniValue::get_str() const
99{
100 if (typ != VSTR)
101 throw std::runtime_error("JSON value is not a string as expected");
102 return getValStr();
103}
104
106{
107 if (typ != VNUM)
108 throw std::runtime_error("JSON value is not an integer as expected");
109 int32_t retval;
110 if (!ParseInt32(getValStr(), &retval))
111 throw std::runtime_error("JSON integer out of range");
112 return retval;
113}
114
115int64_t UniValue::get_int64() const
116{
117 if (typ != VNUM)
118 throw std::runtime_error("JSON value is not an integer as expected");
119 int64_t retval;
120 if (!ParseInt64(getValStr(), &retval))
121 throw std::runtime_error("JSON integer out of range");
122 return retval;
123}
124
125double UniValue::get_real() const
126{
127 if (typ != VNUM)
128 throw std::runtime_error("JSON value is not a number as expected");
129 double retval;
130 if (!ParseDouble(getValStr(), &retval))
131 throw std::runtime_error("JSON double out of range");
132 return retval;
133}
134
136{
137 if (typ != VOBJ)
138 throw std::runtime_error("JSON value is not an object as expected");
139 return *this;
140}
141
143{
144 if (typ != VARR)
145 throw std::runtime_error("JSON value is not an array as expected");
146 return *this;
147}
148
UniValue::VType typ
Definition: univalue.h:157
const std::string & get_str() const
@ VOBJ
Definition: univalue.h:19
@ VSTR
Definition: univalue.h:19
@ VARR
Definition: univalue.h:19
@ VNUM
Definition: univalue.h:19
@ VBOOL
Definition: univalue.h:19
int64_t get_int64() const
const std::string & getValStr() const
Definition: univalue.h:63
const UniValue & get_obj() const
const std::vector< UniValue > & getValues() const
const std::vector< std::string > & getKeys() const
std::vector< UniValue > values
Definition: univalue.h:160
std::vector< std::string > keys
Definition: univalue.h:159
const UniValue & get_array() const
bool getBool() const
Definition: univalue.h:68
double get_real() const
bool get_bool() const
int get_int() const
bool ParseInt32(const std::string &str, int32_t *out)
Convert string to signed 32-bit integer with strict parse error feedback.
bool ParseInt64(const std::string &str, int64_t *out)
Convert string to signed 64-bit integer with strict parse error feedback.
static bool json_isspace(int ch)
Definition: univalue.h:220