Merge commit '9e26ae1c78fe62e23dcca7b22e1cd1a42b45dd25' into univalue-update

This commit is contained in:
Jack Grigg 2021-01-25 19:26:02 +00:00
commit 36e86d3c69
8 changed files with 100 additions and 138 deletions

View File

@ -25,7 +25,6 @@ addons:
- pkg-config
before_script:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew uninstall libtool; brew install libtool; fi
- if [ -n "$USE_SHELL" ]; then export CONFIG_SHELL="$USE_SHELL"; fi
- test -n "$USE_SHELL" && eval '"$USE_SHELL" -c "./autogen.sh"' || ./autogen.sh

View File

@ -12,33 +12,10 @@ an arbitrary depth.
This class is aligned with the JSON standard, [RFC
7159](https://tools.ietf.org/html/rfc7159.html).
## Motivation
## Library usage
UniValue is a reaction to json_spirit, seeking to minimize template
and memory use, providing a straightforward RAII class compatible with
link-time optimization and embedded uses.
## Status
The current production version is available from the [stable-1.0.x branch](https://github.com/jgarzik/univalue/tree/stable-1.0.x).
The current development series is 1.1.x, and is pushed to the `master` branch.
The next stable version will be 1.2.0, to be released immediately
following the conclusion of the 1.1.x series, similar to [this
variant](https://en.wikipedia.org/wiki/Software_versioning#Odd-numbered_versions_for_development_releases)
of semver.
## Installation
This project is a standard GNU
[autotools](https://www.gnu.org/software/automake/manual/html_node/Autotools-Introduction.html)
project. Build and install instructions are available in the `INSTALL`
file provided with GNU autotools.
```
$ ./autogen.sh
$ ./configure
$ make
```
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.
Other projects looking for a maintained library should use the upstream
univalue at https://github.com/jgarzik/univalue.

View File

@ -1,7 +1,7 @@
m4_define([libunivalue_major_version], [1])
m4_define([libunivalue_minor_version], [1])
m4_define([libunivalue_micro_version], [4])
m4_define([libunivalue_interface_age], [4])
m4_define([libunivalue_micro_version], [3])
m4_define([libunivalue_interface_age], [3])
# If you need a modifier for the version number.
# Normally empty, but can be used to make "fixup" releases.
m4_define([libunivalue_extraversion], [])
@ -14,7 +14,7 @@ m4_define([libunivalue_age], [m4_eval(libunivalue_binary_age - libunivalue_inter
m4_define([libunivalue_version], [libunivalue_major_version().libunivalue_minor_version().libunivalue_micro_version()libunivalue_extraversion()])
AC_INIT([univalue], [1.1.1],
AC_INIT([univalue], [1.0.3],
[https://github.com/jgarzik/univalue/])
dnl make the compilation flags quiet unless V=1 is used

View File

@ -14,14 +14,17 @@
#include <map>
#include <cassert>
#include <utility> // std::pair
#include <sstream> // .get_int64()
class UniValue {
public:
enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VBOOL, };
UniValue() : typ(VNULL) {}
UniValue(UniValue::VType type, const std::string& value = std::string()) : typ(type), val(value) {}
UniValue() { typ = VNULL; }
UniValue(UniValue::VType initialType, const std::string& initialStr = "") {
typ = initialType;
val = initialStr;
}
UniValue(uint64_t val_) {
setInt(val_);
}
@ -46,15 +49,6 @@ public:
}
void clear();
void reserve(size_t n) {
if (typ == VOBJ || typ == VARR) {
if (typ == VOBJ)
keys.reserve(n);
values.reserve(n);
} else if (typ != VNULL) {
val.reserve(n);
}
}
bool setNull();
bool setBool(bool val);
@ -90,10 +84,66 @@ public:
bool isObject() const { return (typ == VOBJ); }
bool push_back(const UniValue& val);
bool push_back(const std::string& val_) {
UniValue tmpVal(VSTR, val_);
return push_back(tmpVal);
}
bool push_back(const char *val_) {
std::string s(val_);
return push_back(s);
}
bool push_back(uint64_t val_) {
UniValue tmpVal(val_);
return push_back(tmpVal);
}
bool push_back(int64_t val_) {
UniValue tmpVal(val_);
return push_back(tmpVal);
}
bool push_back(bool val_) {
UniValue tmpVal(val_);
return push_back(tmpVal);
}
bool push_back(int val_) {
UniValue tmpVal(val_);
return push_back(tmpVal);
}
bool push_back(double val_) {
UniValue tmpVal(val_);
return push_back(tmpVal);
}
bool push_backV(const std::vector<UniValue>& vec);
void _pushKV(const std::string& key, const UniValue& val);
bool pushKV(const std::string& key, const UniValue& val);
bool pushKV(const std::string& key, const std::string& val_) {
UniValue tmpVal(VSTR, val_);
return pushKV(key, tmpVal);
}
bool pushKV(const std::string& key, const char *val_) {
std::string _val(val_);
return pushKV(key, _val);
}
bool pushKV(const std::string& key, int64_t val_) {
UniValue tmpVal(val_);
return pushKV(key, tmpVal);
}
bool pushKV(const std::string& key, uint64_t val_) {
UniValue tmpVal(val_);
return pushKV(key, tmpVal);
}
bool pushKV(const std::string& key, bool val_) {
UniValue tmpVal(val_);
return pushKV(key, tmpVal);
}
bool pushKV(const std::string& key, int val_) {
UniValue tmpVal((int64_t)val_);
return pushKV(key, tmpVal);
}
bool pushKV(const std::string& key, double val_) {
UniValue tmpVal(val_);
return pushKV(key, tmpVal);
}
bool pushKVs(const UniValue& obj);
std::string write(unsigned int prettyIndent = 0,
@ -129,76 +179,9 @@ public:
const UniValue& get_array() const;
enum VType type() const { return getType(); }
bool push_back(std::pair<std::string,UniValue> pear) {
return pushKV(pear.first, pear.second);
}
friend const UniValue& find_value( const UniValue& obj, const std::string& name);
};
//
// The following were added for compatibility with json_spirit.
// Most duplicate other methods, and should be removed.
//
static inline std::pair<std::string,UniValue> Pair(const char *cKey, const char *cVal)
{
std::string key(cKey);
UniValue uVal(cVal);
return std::make_pair(key, uVal);
}
static inline std::pair<std::string,UniValue> Pair(const char *cKey, std::string strVal)
{
std::string key(cKey);
UniValue uVal(strVal);
return std::make_pair(key, uVal);
}
static inline std::pair<std::string,UniValue> Pair(const char *cKey, uint64_t u64Val)
{
std::string key(cKey);
UniValue uVal(u64Val);
return std::make_pair(key, uVal);
}
static inline std::pair<std::string,UniValue> Pair(const char *cKey, int64_t i64Val)
{
std::string key(cKey);
UniValue uVal(i64Val);
return std::make_pair(key, uVal);
}
static inline std::pair<std::string,UniValue> Pair(const char *cKey, bool iVal)
{
std::string key(cKey);
UniValue uVal(iVal);
return std::make_pair(key, uVal);
}
static inline std::pair<std::string,UniValue> Pair(const char *cKey, int iVal)
{
std::string key(cKey);
UniValue uVal(iVal);
return std::make_pair(key, uVal);
}
static inline std::pair<std::string,UniValue> Pair(const char *cKey, double dVal)
{
std::string key(cKey);
UniValue uVal(dVal);
return std::make_pair(key, uVal);
}
static inline std::pair<std::string,UniValue> Pair(const char *cKey, const UniValue& uVal)
{
std::string key(cKey);
return std::make_pair(key, uVal);
}
static inline std::pair<std::string,UniValue> Pair(std::string key, const UniValue& uVal)
{
return std::make_pair(key, uVal);
}
enum jtokentype {
JTOK_ERR = -1,
JTOK_NONE = 0, // eof

View File

@ -11,7 +11,6 @@
#include <vector>
#include <limits>
#include <string>
#include <sstream>
#include "univalue.h"
@ -36,7 +35,7 @@ bool ParseInt32(const std::string& str, int32_t *out)
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 a over/underflow
// 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 &&

View File

@ -273,7 +273,7 @@ bool UniValue::read(const char *raw, size_t size)
tok = getJsonToken(tokenVal, consumed, raw, end);
if (tok == JTOK_NONE || tok == JTOK_ERR)
goto return_fail;
return false;
raw += consumed;
bool isValueOpen = jsonTokenIsValue(tok) ||
@ -281,33 +281,33 @@ bool UniValue::read(const char *raw, size_t size)
if (expect(VALUE)) {
if (!isValueOpen)
goto return_fail;
return false;
clearExpect(VALUE);
} else if (expect(ARR_VALUE)) {
bool isArrValue = isValueOpen || (tok == JTOK_ARR_CLOSE);
if (!isArrValue)
goto return_fail;
return false;
clearExpect(ARR_VALUE);
} else if (expect(OBJ_NAME)) {
bool isObjName = (tok == JTOK_OBJ_CLOSE || tok == JTOK_STRING);
if (!isObjName)
goto return_fail;
return false;
} else if (expect(COLON)) {
if (tok != JTOK_COLON)
goto return_fail;
return false;
clearExpect(COLON);
} else if (!expect(COLON) && (tok == JTOK_COLON)) {
goto return_fail;
return false;
}
if (expect(NOT_VALUE)) {
if (isValueOpen)
goto return_fail;
return false;
clearExpect(NOT_VALUE);
}
@ -332,7 +332,7 @@ bool UniValue::read(const char *raw, size_t size)
}
if (stack.size() > MAX_JSON_DEPTH)
goto return_fail;
return false;
if (utyp == VOBJ)
setExpect(OBJ_NAME);
@ -344,12 +344,12 @@ bool UniValue::read(const char *raw, size_t size)
case JTOK_OBJ_CLOSE:
case JTOK_ARR_CLOSE: {
if (!stack.size() || (last_tok == JTOK_COMMA))
goto return_fail;
return false;
VType utyp = (tok == JTOK_OBJ_CLOSE ? VOBJ : VARR);
UniValue *top = stack.back();
if (utyp != top->getType())
goto return_fail;
return false;
stack.pop_back();
clearExpect(OBJ_NAME);
@ -359,11 +359,11 @@ bool UniValue::read(const char *raw, size_t size)
case JTOK_COLON: {
if (!stack.size())
goto return_fail;
return false;
UniValue *top = stack.back();
if (top->getType() != VOBJ)
goto return_fail;
return false;
setExpect(VALUE);
break;
@ -372,7 +372,7 @@ bool UniValue::read(const char *raw, size_t size)
case JTOK_COMMA: {
if (!stack.size() ||
(last_tok == JTOK_COMMA) || (last_tok == JTOK_ARR_OPEN))
goto return_fail;
return false;
UniValue *top = stack.back();
if (top->getType() == VOBJ)
@ -446,19 +446,15 @@ bool UniValue::read(const char *raw, size_t size)
}
default:
goto return_fail;
return false;
}
} while (!stack.empty ());
/* Check that nothing follows the initial construct (parsed above). */
tok = getJsonToken(tokenVal, consumed, raw, end);
if (tok != JTOK_NONE)
goto return_fail;
return false;
return true;
return_fail:
clear();
return false;
}

View File

@ -3,6 +3,7 @@
// file COPYING or https://opensource.org/licenses/mit-license.php.
#include <iomanip>
#include <sstream>
#include <stdio.h>
#include "univalue.h"
#include "univalue_escapes.h"

View File

@ -142,8 +142,6 @@ BOOST_AUTO_TEST_CASE(univalue_set)
BOOST_CHECK(v.isArray());
BOOST_CHECK_EQUAL(v.size(), 0);
BOOST_CHECK(v.setStr(""));
v.reserve(3);
BOOST_CHECK(v.setStr("zum"));
BOOST_CHECK(v.isStr());
BOOST_CHECK_EQUAL(v.getValStr(), "zum");
@ -189,7 +187,6 @@ BOOST_AUTO_TEST_CASE(univalue_set)
BOOST_AUTO_TEST_CASE(univalue_array)
{
UniValue arr(UniValue::VARR);
arr.reserve(9);
UniValue v((int64_t)1023LL);
BOOST_CHECK(arr.push_back(v));
@ -213,19 +210,31 @@ BOOST_AUTO_TEST_CASE(univalue_array)
BOOST_CHECK(arr.push_back((int64_t) -400LL));
BOOST_CHECK(arr.push_back((int) -401));
BOOST_CHECK(arr.push_back(-40.1));
BOOST_CHECK(arr.push_back(true));
BOOST_CHECK_EQUAL(arr.empty(), false);
BOOST_CHECK_EQUAL(arr.size(), 9);
BOOST_CHECK_EQUAL(arr.size(), 10);
BOOST_CHECK_EQUAL(arr[0].getValStr(), "1023");
BOOST_CHECK_EQUAL(arr[0].getType(), UniValue::VNUM);
BOOST_CHECK_EQUAL(arr[1].getValStr(), "zippy");
BOOST_CHECK_EQUAL(arr[1].getType(), UniValue::VSTR);
BOOST_CHECK_EQUAL(arr[2].getValStr(), "pippy");
BOOST_CHECK_EQUAL(arr[2].getType(), UniValue::VSTR);
BOOST_CHECK_EQUAL(arr[3].getValStr(), "boing");
BOOST_CHECK_EQUAL(arr[3].getType(), UniValue::VSTR);
BOOST_CHECK_EQUAL(arr[4].getValStr(), "going");
BOOST_CHECK_EQUAL(arr[4].getType(), UniValue::VSTR);
BOOST_CHECK_EQUAL(arr[5].getValStr(), "400");
BOOST_CHECK_EQUAL(arr[5].getType(), UniValue::VNUM);
BOOST_CHECK_EQUAL(arr[6].getValStr(), "-400");
BOOST_CHECK_EQUAL(arr[6].getType(), UniValue::VNUM);
BOOST_CHECK_EQUAL(arr[7].getValStr(), "-401");
BOOST_CHECK_EQUAL(arr[7].getType(), UniValue::VNUM);
BOOST_CHECK_EQUAL(arr[8].getValStr(), "-40.1");
BOOST_CHECK_EQUAL(arr[8].getType(), UniValue::VNUM);
BOOST_CHECK_EQUAL(arr[9].getValStr(), "1");
BOOST_CHECK_EQUAL(arr[9].getType(), UniValue::VBOOL);
BOOST_CHECK_EQUAL(arr[999].getValStr(), "");
@ -240,8 +249,6 @@ BOOST_AUTO_TEST_CASE(univalue_object)
std::string strKey, strVal;
UniValue v;
obj.reserve(11);
strKey = "age";
v.setInt(100);
BOOST_CHECK(obj.pushKV(strKey, v));