Skip to content

Commit

Permalink
Squashed 'src/univalue/' changes from a44caf65fe..6c19d050a9
Browse files Browse the repository at this point in the history
6c19d050a9 Merge bitcoin-core/univalue-subtree#33: Add getInt<Integral>() helper
09e4a930fc Add getInt helper
10619e0d9a Merge bitcoin-core/univalue-subtree#32: refactor: include-what-you-use
431cdf5d27 refactor: use constexpr where appropriate
64fc881fa4 refactor: cleanup headers for iwyu
9c35bf38eb Merge bitcoin-core/univalue-subtree#30: doc: note that our API has diverged from upstream
09b65facb9 doc: note that our API has diverged from upstream

git-subtree-dir: src/univalue
git-subtree-split: 6c19d050a9bcb2be216121db0df57c930a9ee12e
  • Loading branch information
MacroFake committed May 12, 2022
1 parent 9b49ed6 commit f403531
Show file tree
Hide file tree
Showing 12 changed files with 74 additions and 96 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ This class is aligned with the JSON standard, [RFC
## Library usage

This is a fork of univalue used by Bitcoin Core. It is not maintained for usage
by other projects. Notably, the API may break in non-backward-compatible ways.
by other projects. Notably, the API is broken in non-backward-compatible ways.

Other projects looking for a maintained library should use the upstream
univalue at https://github.com/jgarzik/univalue.
4 changes: 2 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ AC_SUBST(LIBUNIVALUE_AGE)
LT_INIT
LT_LANG([C++])

dnl Require C++11 compiler (no GNU extensions)
AX_CXX_COMPILE_STDCXX([11], [noext], [mandatory], [nodefault])
dnl Require C++17 compiler (no GNU extensions)
AX_CXX_COMPILE_STDCXX([17], [noext], [mandatory], [nodefault])

case $host in
*mingw*)
Expand Down
8 changes: 5 additions & 3 deletions gen/gen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
// $ ./gen > univalue_escapes.h
//

#include <stdio.h>
#include <string.h>
#include "univalue.h"
#include <univalue.h>

#include <cstdio>
#include <cstring>
#include <string>

static bool initEscapes;
static std::string escapes[256];
Expand Down
29 changes: 22 additions & 7 deletions include/univalue.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
#ifndef __UNIVALUE_H__
#define __UNIVALUE_H__

#include <stdint.h>
#include <string.h>

#include <charconv>
#include <cstdint>
#include <cstring>
#include <map>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <vector>
#include <map>
#include <cassert>

class UniValue {
public:
Expand Down Expand Up @@ -168,10 +169,24 @@ class UniValue {
// value is of unexpected type
const std::vector<std::string>& getKeys() const;
const std::vector<UniValue>& getValues() const;
template <typename Int>
auto getInt() const
{
static_assert(std::is_integral<Int>::value);
if (typ != VNUM) {
throw std::runtime_error("JSON value is not an integer as expected");
}
Int result;
const auto [first_nonmatching, error_condition] = std::from_chars(val.data(), val.data() + val.size(), result);
if (first_nonmatching != val.data() + val.size() || error_condition != std::errc{}) {
throw std::runtime_error("JSON integer out of range");
}
return result;
}
bool get_bool() const;
const std::string& get_str() const;
int get_int() const;
int64_t get_int64() const;
auto get_int() const { return getInt<int>(); };
auto get_int64() const { return getInt<int64_t>(); };
double get_real() const;
const UniValue& get_obj() const;
const UniValue& get_array() const;
Expand Down
11 changes: 7 additions & 4 deletions lib/univalue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.

#include <stdint.h>
#include <univalue.h>

#include <iomanip>
#include <map>
#include <memory>
#include <sstream>
#include <stdlib.h>

#include "univalue.h"
#include <string>
#include <utility>
#include <vector>

const UniValue NullUniValue;

Expand Down
70 changes: 10 additions & 60 deletions lib/univalue_get.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.

#include <stdint.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdexcept>
#include <vector>
#include <univalue.h>

#include <cerrno>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <limits>
#include <string>
#include <locale>
#include <sstream>

#include "univalue.h"
#include <stdexcept>
#include <string>
#include <vector>

namespace
{
Expand All @@ -28,37 +29,6 @@ static bool ParsePrechecks(const std::string& str)
return true;
}

bool ParseInt32(const std::string& str, int32_t *out)
{
if (!ParsePrechecks(str))
return false;
char *endp = nullptr;
errno = 0; // strtol will not set errno if valid
long int n = strtol(str.c_str(), &endp, 10);
if(out) *out = (int32_t)n;
// Note that strtol returns a *long int*, so even if strtol doesn't report an over/underflow
// we still have to check that the returned value is within the range of an *int32_t*. On 64-bit
// platforms the size of these types may be different.
return endp && *endp == 0 && !errno &&
n >= std::numeric_limits<int32_t>::min() &&
n <= std::numeric_limits<int32_t>::max();
}

bool ParseInt64(const std::string& str, int64_t *out)
{
if (!ParsePrechecks(str))
return false;
char *endp = nullptr;
errno = 0; // strtoll will not set errno if valid
long long int n = strtoll(str.c_str(), &endp, 10);
if(out) *out = (int64_t)n;
// Note that strtoll returns a *long long int*, so even if strtol doesn't report a over/underflow
// we still have to check that the returned value is within the range of an *int64_t*.
return endp && *endp == 0 && !errno &&
n >= std::numeric_limits<int64_t>::min() &&
n <= std::numeric_limits<int64_t>::max();
}

bool ParseDouble(const std::string& str, double *out)
{
if (!ParsePrechecks(str))
Expand Down Expand Up @@ -102,26 +72,6 @@ const std::string& UniValue::get_str() const
return getValStr();
}

int UniValue::get_int() const
{
if (typ != VNUM)
throw std::runtime_error("JSON value is not an integer as expected");
int32_t retval;
if (!ParseInt32(getValStr(), &retval))
throw std::runtime_error("JSON integer out of range");
return retval;
}

int64_t UniValue::get_int64() const
{
if (typ != VNUM)
throw std::runtime_error("JSON value is not an integer as expected");
int64_t retval;
if (!ParseInt64(getValStr(), &retval))
throw std::runtime_error("JSON integer out of range");
return retval;
}

double UniValue::get_real() const
{
if (typ != VNUM)
Expand Down
13 changes: 8 additions & 5 deletions lib/univalue_read.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,22 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.

#include <string.h>
#include <vector>
#include <stdio.h>
#include "univalue.h"
#include <univalue.h>
#include "univalue_utffilter.h"

#include <cstdio>
#include <cstdint>
#include <cstring>
#include <string>
#include <vector>

/*
* According to stackexchange, the original json test suite wanted
* to limit depth to 22. Widely-deployed PHP bails at depth 512,
* so we will follow PHP's lead, which should be more than sufficient
* (further stackexchange comments indicate depth > 32 rarely occurs).
*/
static const size_t MAX_JSON_DEPTH = 512;
static constexpr size_t MAX_JSON_DEPTH = 512;

static bool json_isdigit(int ch)
{
Expand Down
8 changes: 5 additions & 3 deletions lib/univalue_write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.

#include <iomanip>
#include <stdio.h>
#include "univalue.h"
#include <univalue.h>
#include "univalue_escapes.h"

#include <memory>
#include <string>
#include <vector>

static std::string json_escape(const std::string& inS)
{
std::string outS;
Expand Down
2 changes: 1 addition & 1 deletion test/no_nul.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "univalue.h"
#include <univalue.h>

int main (int argc, char *argv[])
{
Expand Down
12 changes: 7 additions & 5 deletions test/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.

#include <stdint.h>
#include <vector>
#include <string>
#include <map>
#include <univalue.h>

#include <cassert>
#include <cstdint>
#include <map>
#include <memory>
#include <stdexcept>
#include <univalue.h>
#include <string>
#include <vector>

#define BOOST_FIXTURE_TEST_SUITE(a, b)
#define BOOST_AUTO_TEST_CASE(funcName) void funcName()
Expand Down
4 changes: 3 additions & 1 deletion test/test_json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
// It reads JSON input from stdin and exits with code 0 if it can be parsed
// successfully. It also pretty prints the parsed JSON value to stdout.

#include <univalue.h>

#include <iostream>
#include <iterator>
#include <string>
#include "univalue.h"

using namespace std;

Expand Down
7 changes: 3 additions & 4 deletions test/unitester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <univalue.h>

#include <cassert>
#include <cstdio>
#include <string>
#include "univalue.h"

#ifndef JSON_TEST_SRC
#error JSON_TEST_SRC must point to test source directory
Expand Down

0 comments on commit f403531

Please sign in to comment.