univalue_get.cpp raw
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 <univalue.h>
7
8 #include <cstring>
9 #include <locale>
10 #include <optional>
11 #include <sstream>
12 #include <stdexcept>
13 #include <string>
14 #include <vector>
15
16 namespace
17 {
18 static bool ParsePrechecks(const std::string& str)
19 {
20 if (str.empty()) // No empty string allowed
21 return false;
22 if (str.size() >= 1 && (json_isspace(str[0]) || json_isspace(str[str.size()-1]))) // No padding allowed
23 return false;
24 if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed
25 return false;
26 return true;
27 }
28
29 std::optional<double> ParseDouble(const std::string& str)
30 {
31 if (!ParsePrechecks(str))
32 return std::nullopt;
33 if (str.size() >= 2 && str[0] == '0' && str[1] == 'x') // No hexadecimal floats allowed
34 return std::nullopt;
35 std::istringstream text(str);
36 text.imbue(std::locale::classic());
37 double result;
38 text >> result;
39 if (!text.eof() || text.fail()) {
40 return std::nullopt;
41 }
42 return result;
43 }
44 }
45
46 const std::vector<std::string>& UniValue::getKeys() const
47 {
48 checkType(VOBJ);
49 return keys;
50 }
51
52 const std::vector<UniValue>& UniValue::getValues() const
53 {
54 if (typ != VOBJ && typ != VARR)
55 throw std::runtime_error("JSON value is not an object or array as expected");
56 return values;
57 }
58
59 bool UniValue::get_bool() const
60 {
61 checkType(VBOOL);
62 return isTrue();
63 }
64
65 const std::string& UniValue::get_str() const
66 {
67 checkType(VSTR);
68 return getValStr();
69 }
70
71 double UniValue::get_real() const
72 {
73 checkType(VNUM);
74 if (const auto retval{ParseDouble(getValStr())}) {
75 return *retval;
76 }
77 throw std::runtime_error("JSON double out of range");
78 }
79
80 const UniValue& UniValue::get_obj() const
81 {
82 checkType(VOBJ);
83 return *this;
84 }
85
86 const UniValue& UniValue::get_array() const
87 {
88 checkType(VARR);
89 return *this;
90 }
91