Page MenuHomePhabricator

No OneTemporary

diff --git a/.arclint b/.arclint
index ac8dfb101..5043fbd8c 100644
--- a/.arclint
+++ b/.arclint
@@ -1,322 +1,322 @@
{
"linters": {
"generated": {
"type": "generated"
},
"clang-format": {
"type": "clang-format",
"version": ">=12.0",
"bin": [
"clang-format-12",
"clang-format"
],
"include": "(^(src|chronik)/.*\\.(h|c|cpp|mm)$)",
"exclude": [
- "(^src/(secp256k1|univalue|leveldb)/)",
+ "(^src/(secp256k1|leveldb)/)",
"(^src/bench/nanobench.h$)"
]
},
"black": {
"type": "black",
"version": ">=24.0.0",
"include": [
"(\\.py$)",
"(^electrum/electrum-abc$)"
],
"exclude": [
"(^contrib/apple-sdk-tools/)",
"(^electrum/electrumabc_gui/qt/icons.py)",
"(\\_pb2.py$)"
]
},
"flake8": {
"type": "flake8",
"version": ">=5.0",
"include": [
"(\\.py$)",
"(^electrum/electrum-abc$)"
],
"exclude": [
"(^contrib/apple-sdk-tools/)",
"(^electrum/electrumabc_gui/qt/icons.py)",
"(\\_pb2.py$)"
],
"flags": [
"--ignore=A003,E203,E303,E305,E501,E704,W503,W504",
"--require-plugins=flake8-comprehensions,flake8-builtins"
]
},
"lint-format-strings": {
"type": "lint-format-strings",
"include": "(^(src|chronik)/.*\\.(h|c|cpp)$)",
"exclude": [
"(^src/(secp256k1|leveldb)/)",
"(^src/bench/nanobench.h$)",
"(^src/test/fuzz/strprintf.cpp$)"
]
},
"check-doc": {
"type": "check-doc",
"include": "(^(src|chronik)/.*\\.(h|c|cpp)$)"
},
"lint-tests": {
"type": "lint-tests",
"include": "(^src/(seeder/|rpc/|wallet/)?test/.*\\.(cpp)$)"
},
"phpcs": {
"type": "phpcs",
"include": "(\\.php$)",
"exclude": [
"(^arcanist/__phutil_library_.+\\.php$)"
],
"phpcs.standard": "arcanist/phpcs.xml"
},
"lint-locale-dependence": {
"type": "lint-locale-dependence",
"include": "(^(src|chronik)/.*\\.(h|cpp)$)",
"exclude": [
"(^src/(crypto/ctaes/|leveldb/|secp256k1/|tinyformat.h))",
"(^src/bench/nanobench.h$)"
]
},
"lint-cheader": {
"type": "lint-cheader",
"include": "(^(src|chronik)/.*\\.(h|cpp)$)",
"exclude": [
"(^src/(crypto/ctaes|secp256k1|leveldb)/)",
"(^src/bench/nanobench.h$)"
]
},
"spelling": {
"type": "spelling",
"exclude": [
"(^build-aux/m4/)",
"(^depends/)",
"(^doc/release-notes/)",
"(^src/(qt/locale|secp256k1|leveldb)/)",
"(^test/lint/dictionary/)",
"(^web/e.cash/public/animations/)",
"(package-lock.json)",
"(^electrum/electrumabc/wordlist/)"
],
"spelling.dictionaries": [
"test/lint/dictionary/english.json"
]
},
"lint-assert-with-side-effects": {
"type": "lint-assert-with-side-effects",
"include": "(^(src|chronik)/.*\\.(h|cpp)$)",
"exclude": [
"(^src/(secp256k1|leveldb)/)",
"(^src/bench/nanobench.h$)"
]
},
"lint-include-quotes": {
"type": "lint-include-quotes",
"include": "(^(src|chronik)/.*\\.(h|cpp)$)",
"exclude": [
"(^src/(secp256k1|leveldb)/)",
"(^src/bench/nanobench.h$)"
]
},
"lint-include-guard": {
"type": "lint-include-guard",
"include": "(^(src|chronik)/.*\\.h$)",
"exclude": [
"(^src/(crypto/ctaes|secp256k1|leveldb)/)",
"(^src/bench/nanobench.h$)",
"(^src/tinyformat.h$)"
]
},
"lint-include-source": {
"type": "lint-include-source",
"include": "(^(src|chronik)/.*\\.(h|c|cpp)$)",
"exclude": [
"(^src/(secp256k1|leveldb)/)",
"(^src/bench/nanobench.h$)"
]
},
"lint-std-chrono": {
"type": "lint-std-chrono",
"include": "(^(src|chronik)/.*\\.(h|cpp)$)"
},
"lint-stdint": {
"type": "lint-stdint",
"include": "(^(src|chronik)/.*\\.(h|c|cpp)$)",
"exclude": [
"(^src/(secp256k1|leveldb)/)",
"(^src/bench/nanobench.h$)",
"(^src/compat/assumptions.h$)"
]
},
"check-files": {
"type": "check-files"
},
"lint-boost-dependencies": {
"type": "lint-boost-dependencies",
"include": "(^(src|chronik)/.*\\.(h|cpp)$)"
},
"lint-python-encoding": {
"type": "lint-python-encoding",
"include": "(\\.py$)",
"exclude": [
"(^contrib/apple-sdk-tools/)"
]
},
"shellcheck": {
"type": "shellcheck",
"version": ">=0.7.0",
"flags": [
"--external-sources",
"--source-path=SCRIPTDIR"
],
"include": "(\\.(sh|bash)$)",
"exclude": [
"(^src/(secp256k1)/)",
"(^electrum/)"
]
},
"lint-shell-locale": {
"type": "lint-shell-locale",
"include": "(\\.(sh|bash)$)",
"exclude": [
"(^src/(secp256k1)/)",
"(^cmake/utils/log-and-print-on-failure.sh)"
]
},
"lint-cpp-void-parameters": {
"type": "lint-cpp-void-parameters",
"include": "(^(src|chronik)/.*\\.(h|cpp)$)",
"exclude": [
"(^src/(crypto/ctaes|secp256k1|leveldb)/)",
"(^src/bench/nanobench.h$)",
"(^src/compat/glibc_compat.cpp$)"
]
},
"lint-logs": {
"type": "lint-logs",
"include": "(^(src|chronik)/.*\\.(h|cpp|rs)$)"
},
"lint-qt": {
"type": "lint-qt",
"include": "(^src/qt/.*\\.(h|cpp)$)",
"exclude": [
"(^src/qt/(locale|forms|res)/)"
]
},
"lint-doxygen": {
"type": "lint-doxygen",
"include": "(^(src|chronik)/.*\\.(h|c|cpp)$)",
"exclude": [
"(^src/(crypto/ctaes|secp256k1|leveldb)/)",
"(^src/bench/nanobench.h$)"
]
},
"lint-whitespace": {
"type": "lint-whitespace",
"include": "(\\.(ac|am|cmake|conf|in|include|json|m4|md|openrc|php|pl|rs|sh|txt|yml)$)",
"exclude": [
"(^src/(secp256k1|leveldb)/)",
"(^src/bench/nanobench.h$)"
]
},
"yamllint": {
"type": "yamllint",
"include": "(\\.(yml|yaml)$)",
"exclude": "(^src/(secp256k1|leveldb)/)"
},
"lint-check-nonfatal": {
"type": "lint-check-nonfatal",
"include": [
"(^src/rpc/.*\\.(h|c|cpp)$)",
"(^src/wallet/rpc*.*\\.(h|c|cpp)$)"
],
"exclude": "(^src/rpc/server.cpp)"
},
"lint-markdown": {
"type": "lint-markdown",
"include": [
"(\\.md$)"
],
"exclude": [
"(^modules/docs/chronik.e.cash/)"
]
},
"lint-python-mypy": {
"type": "lint-python-mypy",
"version": ">=0.910",
"include": "(\\.py$)",
"exclude": [
"(^contrib/apple-sdk-tools/)",
"(^contrib/macdeploy/)",
"(^electrum/)"
],
"flags": [
"--ignore-missing-imports",
"--install-types",
"--non-interactive"
]
},
"lint-python-mutable-default": {
"type": "lint-python-mutable-default",
"include": "(\\.py$)",
"exclude": [
"(^contrib/apple-sdk-tools/)"
]
},
"prettier": {
"type": "prettier",
"version": ">=2.6.0",
"include": [
"(^apps/.*\\.(css|html|js|json|jsx|md|scss|ts|tsx)$)",
"(^doc/standards/.*\\.(css|html|js|json|jsx|md|scss|ts|tsx)$)",
"(^cashtab/.*\\.(css|html|js|json|jsx|md|scss|ts|tsx)$)",
"(^modules/.*\\.(css|html|js|json|jsx|md|scss|ts|tsx)$)",
"(^web/.*\\.(css|html|js|json|jsx|md|scss|ts|tsx)$)"
],
"exclude": [
"(^web/.*/translations/.*\\.json$)",
"(^web/e.cash/public/animations/)"
]
},
"lint-python-isort": {
"type": "lint-python-isort",
"version": ">=5.6.4",
"include": [
"(\\.py$)",
"(^electrum/electrum-abc$)"
],
"exclude": [
"(^contrib/apple-sdk-tools/)",
"(^electrum/electrumabc_gui/qt/icons.py)",
"(\\_pb2.py$)"
]
},
"rustfmt": {
"type": "rustfmt",
"version": ">=1.5.1",
"include": "(\\.rs$)"
},
"eslint": {
"type": "eslint",
"version": ">=8.0.0",
"include": [
"(cashtab/.*\\.js$)",
"(apps/alias-server/.*\\.js$)",
"(modules/ecashaddrjs/.*\\.js$)",
"(apps/ecash-herald/.*\\.js$)",
"(modules/chronik-client/.*\\.(js|jsx|ts|tsx)$)",
"(^web/e.cash/.*\\.js$)"
]
},
"lint-python-flynt": {
"type": "lint-python-flynt",
"version": ">=0.78",
"include": "(\\.py$)",
"exclude": [
"(^contrib/apple-sdk-tools/)",
"(^electrum/)"
]
}
}
}
diff --git a/src/univalue/include/univalue.h b/src/univalue/include/univalue.h
index 14d48d8e1..1fe46d6af 100644
--- a/src/univalue/include/univalue.h
+++ b/src/univalue/include/univalue.h
@@ -1,218 +1,224 @@
// Copyright 2014 BitPay Inc.
// Copyright 2015 Bitcoin Core Developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_H
#define BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_H
#include <charconv>
#include <cstddef>
#include <cstdint>
#include <map>
#include <stdexcept>
#include <string>
#include <string_view>
#include <system_error>
#include <type_traits>
#include <utility>
#include <vector>
namespace {
- struct UniValueStreamWriter;
+struct UniValueStreamWriter;
}
class UniValue {
friend struct ::UniValueStreamWriter;
public:
- enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VBOOL, };
+ enum VType {
+ VNULL,
+ VOBJ,
+ VARR,
+ VSTR,
+ VNUM,
+ VBOOL,
+ };
- class type_error : public std::runtime_error
- {
+ class type_error : public std::runtime_error {
using std::runtime_error::runtime_error;
};
UniValue() : typ(VNULL) {}
- UniValue(UniValue::VType type, std::string str = {}) : typ(type), val(std::move(str)) {}
- template <typename Ref, typename T = std::remove_cv_t<std::remove_reference_t<Ref>>,
- std::enable_if_t<std::is_floating_point_v<T> || // setFloat
- std::is_same_v<bool, T> || // setBool
- std::is_signed_v<T> || std::is_unsigned_v<T> || // setInt
- std::is_constructible_v<std::string, T>, // setStr
- bool> = true>
- UniValue(Ref&& val)
- {
+ UniValue(UniValue::VType type, std::string str = {})
+ : typ(type), val(std::move(str)) {}
+ template <typename Ref,
+ typename T = std::remove_cv_t<std::remove_reference_t<Ref>>,
+ std::enable_if_t<
+ std::is_floating_point_v<T> || // setFloat
+ std::is_same_v<bool, T> || // setBool
+ std::is_signed_v<T> || std::is_unsigned_v<T> || // setInt
+ std::is_constructible_v<std::string, T>, // setStr
+ bool> = true>
+ UniValue(Ref &&val) {
if constexpr (std::is_floating_point_v<T>) {
setFloat(val);
} else if constexpr (std::is_same_v<bool, T>) {
setBool(val);
} else if constexpr (std::is_signed_v<T>) {
setInt(int64_t{val});
} else if constexpr (std::is_unsigned_v<T>) {
setInt(uint64_t{val});
} else {
setStr(std::string{std::forward<Ref>(val)});
}
}
void clear();
void reserve(size_t n) {
if (typ == VOBJ || typ == VARR) {
- if (typ == VOBJ)
- keys.reserve(n);
+ if (typ == VOBJ) keys.reserve(n);
values.reserve(n);
} else if (typ != VNULL) {
val.reserve(n);
}
}
void setNull();
void setBool(bool val);
void setNumStr(std::string str);
void setInt(uint64_t val);
void setInt(int64_t val);
void setInt(int val_) { return setInt(int64_t{val_}); }
void setFloat(double val);
void setStr(std::string str);
void setArray();
void setObject();
enum VType getType() const { return typ; }
- const std::string& getValStr() const { return val; }
+ const std::string &getValStr() const { return val; }
bool empty() const { return (values.size() == 0); }
size_t size() const { return values.size(); }
- void getObjMap(std::map<std::string,UniValue>& kv) const;
- bool checkObject(const std::map<std::string,UniValue::VType>& memberTypes) const;
- const UniValue& operator[](const std::string& key) const;
- const UniValue& operator[](size_t index) const;
- bool exists(const std::string& key) const { size_t i; return findKey(key, i); }
+ void getObjMap(std::map<std::string, UniValue> &kv) const;
+ bool checkObject(
+ const std::map<std::string, UniValue::VType> &memberTypes) const;
+ const UniValue &operator[](const std::string &key) const;
+ const UniValue &operator[](size_t index) const;
+ bool exists(const std::string &key) const {
+ size_t i;
+ return findKey(key, i);
+ }
bool isNull() const { return (typ == VNULL); }
bool isTrue() const { return (typ == VBOOL) && (val == "1"); }
bool isFalse() const { return (typ == VBOOL) && (val != "1"); }
bool isBool() const { return (typ == VBOOL); }
bool isStr() const { return (typ == VSTR); }
bool isNum() const { return (typ == VNUM); }
bool isArray() const { return (typ == VARR); }
bool isObject() const { return (typ == VOBJ); }
void push_back(UniValue val);
- void push_backV(const std::vector<UniValue>& vec);
- template <class It>
- void push_backV(It first, It last);
+ void push_backV(const std::vector<UniValue> &vec);
+ template <class It> void push_backV(It first, It last);
void pushKVEnd(std::string key, UniValue val);
void pushKV(std::string key, UniValue val);
void pushKVs(UniValue obj);
std::string write(unsigned int prettyIndent = 0,
unsigned int indentLevel = 0) const;
bool read(std::string_view raw);
private:
UniValue::VType typ;
- std::string val; // numbers are stored as C++ strings
+ std::string val; // numbers are stored as C++ strings
std::vector<std::string> keys;
std::vector<UniValue> values;
- void checkType(const VType& expected) const;
- bool findKey(const std::string& key, size_t& retIdx) const;
+ void checkType(const VType &expected) const;
+ bool findKey(const std::string &key, size_t &retIdx) const;
public:
// Strict type-specific getters, these throw std::runtime_error if the
// value is of unexpected type
- const std::vector<std::string>& getKeys() const;
- const std::vector<UniValue>& getValues() const;
- template <typename Int>
- Int getInt() const;
+ const std::vector<std::string> &getKeys() const;
+ const std::vector<UniValue> &getValues() const;
+ template <typename Int> Int getInt() const;
bool get_bool() const;
- const std::string& get_str() const;
+ const std::string &get_str() const;
double get_real() const;
- const UniValue& get_obj() const;
- const UniValue& get_array() const;
+ const UniValue &get_obj() const;
+ const UniValue &get_array() const;
enum VType type() const { return getType(); }
- const UniValue& find_value(std::string_view key) const;
+ const UniValue &find_value(std::string_view key) const;
};
-template <class It>
-void UniValue::push_backV(It first, It last)
-{
+template <class It> void UniValue::push_backV(It first, It last) {
checkType(VARR);
values.insert(values.end(), first, last);
}
-template <typename Int>
-Int UniValue::getInt() const
-{
+template <typename Int> Int UniValue::getInt() const {
static_assert(std::is_integral<Int>::value);
checkType(VNUM);
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{}) {
+ 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;
}
enum jtokentype {
- JTOK_ERR = -1,
- JTOK_NONE = 0, // eof
+ JTOK_ERR = -1,
+ JTOK_NONE = 0, // eof
JTOK_OBJ_OPEN,
JTOK_OBJ_CLOSE,
JTOK_ARR_OPEN,
JTOK_ARR_CLOSE,
JTOK_COLON,
JTOK_COMMA,
JTOK_KW_NULL,
JTOK_KW_TRUE,
JTOK_KW_FALSE,
JTOK_NUMBER,
JTOK_STRING,
};
-extern enum jtokentype getJsonToken(std::string& tokenVal,
- unsigned int& consumed, const char *raw, const char *end);
+extern enum jtokentype getJsonToken(std::string &tokenVal,
+ unsigned int &consumed, const char *raw,
+ const char *end);
extern const char *uvTypeName(UniValue::VType t);
-static inline bool jsonTokenIsValue(enum jtokentype jtt)
-{
+static inline bool jsonTokenIsValue(enum jtokentype jtt) {
switch (jtt) {
- case JTOK_KW_NULL:
- case JTOK_KW_TRUE:
- case JTOK_KW_FALSE:
- case JTOK_NUMBER:
- case JTOK_STRING:
- return true;
-
- default:
- return false;
+ case JTOK_KW_NULL:
+ case JTOK_KW_TRUE:
+ case JTOK_KW_FALSE:
+ case JTOK_NUMBER:
+ case JTOK_STRING:
+ return true;
+
+ default:
+ return false;
}
// not reached
}
-static inline bool json_isspace(int ch)
-{
+static inline bool json_isspace(int ch) {
switch (ch) {
- case 0x20:
- case 0x09:
- case 0x0a:
- case 0x0d:
- return true;
-
- default:
- return false;
+ case 0x20:
+ case 0x09:
+ case 0x0a:
+ case 0x0d:
+ return true;
+
+ default:
+ return false;
}
// not reached
}
extern const UniValue NullUniValue;
#endif // BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_H
diff --git a/src/univalue/include/univalue_escapes.h b/src/univalue/include/univalue_escapes.h
index 83767e8ac..c3f9605a8 100644
--- a/src/univalue/include/univalue_escapes.h
+++ b/src/univalue/include/univalue_escapes.h
@@ -1,261 +1,42 @@
#ifndef BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_ESCAPES_H
#define BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_ESCAPES_H
static const char *escapes[256] = {
- "\\u0000",
- "\\u0001",
- "\\u0002",
- "\\u0003",
- "\\u0004",
- "\\u0005",
- "\\u0006",
- "\\u0007",
- "\\b",
- "\\t",
- "\\n",
- "\\u000b",
- "\\f",
- "\\r",
- "\\u000e",
- "\\u000f",
- "\\u0010",
- "\\u0011",
- "\\u0012",
- "\\u0013",
- "\\u0014",
- "\\u0015",
- "\\u0016",
- "\\u0017",
- "\\u0018",
- "\\u0019",
- "\\u001a",
- "\\u001b",
- "\\u001c",
- "\\u001d",
- "\\u001e",
- "\\u001f",
- nullptr,
- nullptr,
- "\\\"",
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- "\\\\",
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- "\\u007f",
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
+ "\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", "\\u0006",
+ "\\u0007", "\\b", "\\t", "\\n", "\\u000b", "\\f", "\\r",
+ "\\u000e", "\\u000f", "\\u0010", "\\u0011", "\\u0012", "\\u0013", "\\u0014",
+ "\\u0015", "\\u0016", "\\u0017", "\\u0018", "\\u0019", "\\u001a", "\\u001b",
+ "\\u001c", "\\u001d", "\\u001e", "\\u001f", nullptr, nullptr, "\\\"",
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, "\\\\", nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, "\\u007f", nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
};
#endif // BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_ESCAPES_H
diff --git a/src/univalue/include/univalue_utffilter.h b/src/univalue/include/univalue_utffilter.h
index f688eaaa3..37154dc7c 100644
--- a/src/univalue/include/univalue_utffilter.h
+++ b/src/univalue/include/univalue_utffilter.h
@@ -1,119 +1,115 @@
// Copyright 2016 Wladimir J. van der Laan
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_UTFFILTER_H
#define BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_UTFFILTER_H
#include <string>
/**
* Filter that generates and validates UTF-8, as well as collates UTF-16
* surrogate pairs as specified in RFC4627.
*/
-class JSONUTF8StringFilter
-{
+class JSONUTF8StringFilter {
public:
- explicit JSONUTF8StringFilter(std::string &s):
- str(s), is_valid(true), codepoint(0), state(0), surpair(0)
- {
- }
+ explicit JSONUTF8StringFilter(std::string &s)
+ : str(s), is_valid(true), codepoint(0), state(0), surpair(0) {}
// Write single 8-bit char (may be part of UTF-8 sequence)
- void push_back(unsigned char ch)
- {
+ void push_back(uint8_t ch) {
if (state == 0) {
if (ch < 0x80) // 7-bit ASCII, fast direct pass-through
str.push_back(ch);
else if (ch < 0xc0) // Mid-sequence character, invalid in this state
is_valid = false;
else if (ch < 0xe0) { // Start of 2-byte sequence
codepoint = (ch & 0x1f) << 6;
state = 6;
} else if (ch < 0xf0) { // Start of 3-byte sequence
codepoint = (ch & 0x0f) << 12;
state = 12;
} else if (ch < 0xf8) { // Start of 4-byte sequence
codepoint = (ch & 0x07) << 18;
state = 18;
} else // Reserved, invalid
is_valid = false;
} else {
if ((ch & 0xc0) != 0x80) // Not a continuation, invalid
is_valid = false;
state -= 6;
codepoint |= (ch & 0x3f) << state;
- if (state == 0)
- push_back_u(codepoint);
+ if (state == 0) push_back_u(codepoint);
}
}
// Write codepoint directly, possibly collating surrogate pairs
- void push_back_u(unsigned int codepoint_)
- {
+ void push_back_u(unsigned int codepoint_) {
if (state) // Only accept full codepoints in open state
is_valid = false;
- if (codepoint_ >= 0xD800 && codepoint_ < 0xDC00) { // First half of surrogate pair
+ if (codepoint_ >= 0xD800 &&
+ codepoint_ < 0xDC00) { // First half of surrogate pair
if (surpair) // Two subsequent surrogate pair openers - fail
is_valid = false;
else
surpair = codepoint_;
- } else if (codepoint_ >= 0xDC00 && codepoint_ < 0xE000) { // Second half of surrogate pair
+ } else if (codepoint_ >= 0xDC00 &&
+ codepoint_ < 0xE000) { // Second half of surrogate pair
if (surpair) { // Open surrogate pair, expect second half
// Compute code point from UTF-16 surrogate pair
- append_codepoint(0x10000 | ((surpair - 0xD800)<<10) | (codepoint_ - 0xDC00));
+ append_codepoint(0x10000 | ((surpair - 0xD800) << 10) |
+ (codepoint_ - 0xDC00));
surpair = 0;
} else // Second half doesn't follow a first half - fail
is_valid = false;
} else {
- if (surpair) // First half of surrogate pair not followed by second - fail
+ if (surpair) // First half of surrogate pair not followed by second
+ // - fail
is_valid = false;
else
append_codepoint(codepoint_);
}
}
// Check that we're in a state where the string can be ended
// No open sequences, no open surrogate pairs, etc
- bool finalize()
- {
- if (state || surpair)
- is_valid = false;
+ bool finalize() {
+ if (state || surpair) is_valid = false;
return is_valid;
}
+
private:
std::string &str;
bool is_valid;
// Current UTF-8 decoding state
unsigned int codepoint;
int state; // Top bit to be filled in for next UTF-8 byte, or 0
// Keep track of the following state to handle the following section of
// RFC4627:
//
// To escape an extended character that is not in the Basic Multilingual
// Plane, the character is represented as a twelve-character sequence,
// encoding the UTF-16 surrogate pair. So, for example, a string
// containing only the G clef character (U+1D11E) may be represented as
// "\uD834\uDD1E".
//
// Two subsequent \u.... may have to be replaced with one actual codepoint.
unsigned int surpair; // First half of open UTF-16 surrogate pair, or 0
- void append_codepoint(unsigned int codepoint_)
- {
+ void append_codepoint(unsigned int codepoint_) {
if (codepoint_ <= 0x7f)
str.push_back((char)codepoint_);
else if (codepoint_ <= 0x7FF) {
str.push_back((char)(0xC0 | (codepoint_ >> 6)));
str.push_back((char)(0x80 | (codepoint_ & 0x3F)));
} else if (codepoint_ <= 0xFFFF) {
str.push_back((char)(0xE0 | (codepoint_ >> 12)));
str.push_back((char)(0x80 | ((codepoint_ >> 6) & 0x3F)));
str.push_back((char)(0x80 | (codepoint_ & 0x3F)));
} else if (codepoint_ <= 0x1FFFFF) {
str.push_back((char)(0xF0 | (codepoint_ >> 18)));
str.push_back((char)(0x80 | ((codepoint_ >> 12) & 0x3F)));
str.push_back((char)(0x80 | ((codepoint_ >> 6) & 0x3F)));
str.push_back((char)(0x80 | (codepoint_ & 0x3F)));
}
}
};
#endif // BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_UTFFILTER_H
diff --git a/src/univalue/lib/univalue.cpp b/src/univalue/lib/univalue.cpp
index 6ec1dcc54..cf007b396 100644
--- a/src/univalue/lib/univalue.cpp
+++ b/src/univalue/lib/univalue.cpp
@@ -1,242 +1,221 @@
// Copyright 2014 BitPay Inc.
// Copyright 2015 Bitcoin Core Developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.
#include <univalue.h>
#include <iomanip>
#include <map>
#include <memory>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
const UniValue NullUniValue;
-void UniValue::clear()
-{
+void UniValue::clear() {
typ = VNULL;
val.clear();
keys.clear();
values.clear();
}
-void UniValue::setNull()
-{
+void UniValue::setNull() {
clear();
}
-void UniValue::setBool(bool val_)
-{
+void UniValue::setBool(bool val_) {
clear();
typ = VBOOL;
- if (val_)
- val = "1";
+ if (val_) val = "1";
}
-static bool validNumStr(const std::string& s)
-{
+static bool validNumStr(const std::string &s) {
std::string tokenVal;
unsigned int consumed;
- enum jtokentype tt = getJsonToken(tokenVal, consumed, s.data(), s.data() + s.size());
+ enum jtokentype tt =
+ getJsonToken(tokenVal, consumed, s.data(), s.data() + s.size());
return (tt == JTOK_NUMBER);
}
-void UniValue::setNumStr(std::string str)
-{
+void UniValue::setNumStr(std::string str) {
if (!validNumStr(str)) {
- throw std::runtime_error{"The string '" + str + "' is not a valid JSON number"};
+ throw std::runtime_error{"The string '" + str +
+ "' is not a valid JSON number"};
}
clear();
typ = VNUM;
val = std::move(str);
}
-void UniValue::setInt(uint64_t val_)
-{
+void UniValue::setInt(uint64_t val_) {
std::ostringstream oss;
oss << val_;
return setNumStr(oss.str());
}
-void UniValue::setInt(int64_t val_)
-{
+void UniValue::setInt(int64_t val_) {
std::ostringstream oss;
oss << val_;
return setNumStr(oss.str());
}
-void UniValue::setFloat(double val_)
-{
+void UniValue::setFloat(double val_) {
std::ostringstream oss;
oss << std::setprecision(16) << val_;
return setNumStr(oss.str());
}
-void UniValue::setStr(std::string str)
-{
+void UniValue::setStr(std::string str) {
clear();
typ = VSTR;
val = std::move(str);
}
-void UniValue::setArray()
-{
+void UniValue::setArray() {
clear();
typ = VARR;
}
-void UniValue::setObject()
-{
+void UniValue::setObject() {
clear();
typ = VOBJ;
}
-void UniValue::push_back(UniValue val_)
-{
+void UniValue::push_back(UniValue val_) {
checkType(VARR);
values.push_back(std::move(val_));
}
-void UniValue::push_backV(const std::vector<UniValue>& vec)
-{
+void UniValue::push_backV(const std::vector<UniValue> &vec) {
checkType(VARR);
values.insert(values.end(), vec.begin(), vec.end());
}
-void UniValue::pushKVEnd(std::string key, UniValue val_)
-{
+void UniValue::pushKVEnd(std::string key, UniValue val_) {
checkType(VOBJ);
keys.push_back(std::move(key));
values.push_back(std::move(val_));
}
-void UniValue::pushKV(std::string key, UniValue val_)
-{
+void UniValue::pushKV(std::string key, UniValue val_) {
checkType(VOBJ);
size_t idx;
if (findKey(key, idx))
values[idx] = std::move(val_);
else
pushKVEnd(std::move(key), std::move(val_));
}
-void UniValue::pushKVs(UniValue obj)
-{
+void UniValue::pushKVs(UniValue obj) {
checkType(VOBJ);
obj.checkType(VOBJ);
for (size_t i = 0; i < obj.keys.size(); i++)
pushKVEnd(std::move(obj.keys.at(i)), std::move(obj.values.at(i)));
}
-void UniValue::getObjMap(std::map<std::string,UniValue>& kv) const
-{
- if (typ != VOBJ)
- return;
+void UniValue::getObjMap(std::map<std::string, UniValue> &kv) const {
+ if (typ != VOBJ) return;
kv.clear();
for (size_t i = 0; i < keys.size(); i++)
kv[keys[i]] = values[i];
}
-bool UniValue::findKey(const std::string& key, size_t& retIdx) const
-{
+bool UniValue::findKey(const std::string &key, size_t &retIdx) const {
for (size_t i = 0; i < keys.size(); i++) {
if (keys[i] == key) {
retIdx = i;
return true;
}
}
return false;
}
-bool UniValue::checkObject(const std::map<std::string,UniValue::VType>& t) const
-{
+bool UniValue::checkObject(
+ const std::map<std::string, UniValue::VType> &t) const {
if (typ != VOBJ) {
return false;
}
- for (const auto& object: t) {
+ for (const auto &object : t) {
size_t idx = 0;
if (!findKey(object.first, idx)) {
return false;
}
if (values.at(idx).getType() != object.second) {
return false;
}
}
return true;
}
-const UniValue& UniValue::operator[](const std::string& key) const
-{
- if (typ != VOBJ)
- return NullUniValue;
+const UniValue &UniValue::operator[](const std::string &key) const {
+ if (typ != VOBJ) return NullUniValue;
size_t index = 0;
- if (!findKey(key, index))
- return NullUniValue;
+ if (!findKey(key, index)) return NullUniValue;
return values.at(index);
}
-const UniValue& UniValue::operator[](size_t index) const
-{
- if (typ != VOBJ && typ != VARR)
- return NullUniValue;
- if (index >= values.size())
- return NullUniValue;
+const UniValue &UniValue::operator[](size_t index) const {
+ if (typ != VOBJ && typ != VARR) return NullUniValue;
+ if (index >= values.size()) return NullUniValue;
return values.at(index);
}
-void UniValue::checkType(const VType& expected) const
-{
+void UniValue::checkType(const VType &expected) const {
if (typ != expected) {
- throw type_error{"JSON value of type " + std::string{uvTypeName(typ)} + " is not of expected type " +
- std::string{uvTypeName(expected)}};
+ throw type_error{"JSON value of type " + std::string{uvTypeName(typ)} +
+ " is not of expected type " +
+ std::string{uvTypeName(expected)}};
}
}
-const char *uvTypeName(UniValue::VType t)
-{
+const char *uvTypeName(UniValue::VType t) {
switch (t) {
- case UniValue::VNULL: return "null";
- case UniValue::VBOOL: return "bool";
- case UniValue::VOBJ: return "object";
- case UniValue::VARR: return "array";
- case UniValue::VSTR: return "string";
- case UniValue::VNUM: return "number";
+ case UniValue::VNULL:
+ return "null";
+ case UniValue::VBOOL:
+ return "bool";
+ case UniValue::VOBJ:
+ return "object";
+ case UniValue::VARR:
+ return "array";
+ case UniValue::VSTR:
+ return "string";
+ case UniValue::VNUM:
+ return "number";
}
// not reached
return nullptr;
}
-const UniValue& UniValue::find_value(std::string_view key) const
-{
+const UniValue &UniValue::find_value(std::string_view key) const {
for (unsigned int i = 0; i < keys.size(); ++i) {
if (keys[i] == key) {
return values.at(i);
}
}
return NullUniValue;
}
-
diff --git a/src/univalue/lib/univalue_get.cpp b/src/univalue/lib/univalue_get.cpp
index 037449ca0..17533c7f5 100644
--- a/src/univalue/lib/univalue_get.cpp
+++ b/src/univalue/lib/univalue_get.cpp
@@ -1,91 +1,84 @@
// Copyright 2014 BitPay Inc.
// Copyright 2015 Bitcoin Core Developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.
#include <univalue.h>
#include <cerrno>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <limits>
#include <locale>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>
-namespace
-{
-static bool ParsePrechecks(const std::string& str)
-{
+namespace {
+static bool ParsePrechecks(const std::string &str) {
if (str.empty()) // No empty string allowed
return false;
- if (str.size() >= 1 && (json_isspace(str[0]) || json_isspace(str[str.size()-1]))) // No padding allowed
+ if (str.size() >= 1 &&
+ (json_isspace(str[0]) ||
+ json_isspace(str[str.size() - 1]))) // No padding allowed
return false;
if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed
return false;
return true;
}
-bool ParseDouble(const std::string& str, double *out)
-{
- if (!ParsePrechecks(str))
- return false;
- if (str.size() >= 2 && str[0] == '0' && str[1] == 'x') // No hexadecimal floats allowed
+bool ParseDouble(const std::string &str, double *out) {
+ if (!ParsePrechecks(str)) return false;
+ if (str.size() >= 2 && str[0] == '0' &&
+ str[1] == 'x') // No hexadecimal floats allowed
return false;
std::istringstream text(str);
text.imbue(std::locale::classic());
double result;
text >> result;
- if(out) *out = result;
+ if (out) *out = result;
return text.eof() && !text.fail();
}
-}
+} // namespace
-const std::vector<std::string>& UniValue::getKeys() const
-{
+const std::vector<std::string> &UniValue::getKeys() const {
checkType(VOBJ);
return keys;
}
-const std::vector<UniValue>& UniValue::getValues() const
-{
+const std::vector<UniValue> &UniValue::getValues() const {
if (typ != VOBJ && typ != VARR)
- throw std::runtime_error("JSON value is not an object or array as expected");
+ throw std::runtime_error(
+ "JSON value is not an object or array as expected");
return values;
}
-bool UniValue::get_bool() const
-{
+bool UniValue::get_bool() const {
checkType(VBOOL);
return isTrue();
}
-const std::string& UniValue::get_str() const
-{
+const std::string &UniValue::get_str() const {
checkType(VSTR);
return getValStr();
}
-double UniValue::get_real() const
-{
+double UniValue::get_real() const {
checkType(VNUM);
double retval;
if (!ParseDouble(getValStr(), &retval))
throw std::runtime_error("JSON double out of range");
return retval;
}
-const UniValue& UniValue::get_obj() const
-{
+const UniValue &UniValue::get_obj() const {
checkType(VOBJ);
return *this;
}
-const UniValue& UniValue::get_array() const
-{
+const UniValue &UniValue::get_array() const {
checkType(VARR);
return *this;
}
diff --git a/src/univalue/lib/univalue_read.cpp b/src/univalue/lib/univalue_read.cpp
index 9eaf5f337..485b66846 100644
--- a/src/univalue/lib/univalue_read.cpp
+++ b/src/univalue/lib/univalue_read.cpp
@@ -1,469 +1,459 @@
// Copyright 2014 BitPay Inc.
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.
#include <univalue.h>
#include <univalue_utffilter.h>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <string>
#include <string_view>
#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 constexpr size_t MAX_JSON_DEPTH = 512;
-static bool json_isdigit(int ch)
-{
+static bool json_isdigit(int ch) {
return ((ch >= '0') && (ch <= '9'));
}
// convert hexadecimal string to unsigned integer
static const char *hatoui(const char *first, const char *last,
- unsigned int& out)
-{
+ unsigned int &out) {
unsigned int result = 0;
- for (; first != last; ++first)
- {
+ for (; first != last; ++first) {
int digit;
if (json_isdigit(*first))
digit = *first - '0';
else if (*first >= 'a' && *first <= 'f')
digit = *first - 'a' + 10;
else if (*first >= 'A' && *first <= 'F')
digit = *first - 'A' + 10;
else
break;
result = 16 * result + digit;
}
out = result;
return first;
}
-enum jtokentype getJsonToken(std::string& tokenVal, unsigned int& consumed,
- const char *raw, const char *end)
-{
+enum jtokentype getJsonToken(std::string &tokenVal, unsigned int &consumed,
+ const char *raw, const char *end) {
tokenVal.clear();
consumed = 0;
const char *rawStart = raw;
- while (raw < end && (json_isspace(*raw))) // skip whitespace
+ while (raw < end && (json_isspace(*raw))) // skip whitespace
raw++;
- if (raw >= end)
- return JTOK_NONE;
+ if (raw >= end) return JTOK_NONE;
switch (*raw) {
-
- case '{':
- raw++;
- consumed = (raw - rawStart);
- return JTOK_OBJ_OPEN;
- case '}':
- raw++;
- consumed = (raw - rawStart);
- return JTOK_OBJ_CLOSE;
- case '[':
- raw++;
- consumed = (raw - rawStart);
- return JTOK_ARR_OPEN;
- case ']':
- raw++;
- consumed = (raw - rawStart);
- return JTOK_ARR_CLOSE;
-
- case ':':
- raw++;
- consumed = (raw - rawStart);
- return JTOK_COLON;
- case ',':
- raw++;
- consumed = (raw - rawStart);
- return JTOK_COMMA;
-
- case 'n':
- case 't':
- case 'f':
- if (!strncmp(raw, "null", 4)) {
- raw += 4;
+ case '{':
+ raw++;
consumed = (raw - rawStart);
- return JTOK_KW_NULL;
- } else if (!strncmp(raw, "true", 4)) {
- raw += 4;
+ return JTOK_OBJ_OPEN;
+ case '}':
+ raw++;
consumed = (raw - rawStart);
- return JTOK_KW_TRUE;
- } else if (!strncmp(raw, "false", 5)) {
- raw += 5;
+ return JTOK_OBJ_CLOSE;
+ case '[':
+ raw++;
consumed = (raw - rawStart);
- return JTOK_KW_FALSE;
- } else
- return JTOK_ERR;
-
- case '-':
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9': {
- // part 1: int
- std::string numStr;
-
- const char *first = raw;
-
- const char *firstDigit = first;
- if (!json_isdigit(*firstDigit))
- firstDigit++;
- if ((*firstDigit == '0') && json_isdigit(firstDigit[1]))
- return JTOK_ERR;
-
- numStr += *raw; // copy first char
- raw++;
-
- if ((*first == '-') && (raw < end) && (!json_isdigit(*raw)))
- return JTOK_ERR;
+ return JTOK_ARR_OPEN;
+ case ']':
+ raw++;
+ consumed = (raw - rawStart);
+ return JTOK_ARR_CLOSE;
- while (raw < end && json_isdigit(*raw)) { // copy digits
- numStr += *raw;
+ case ':':
raw++;
- }
+ consumed = (raw - rawStart);
+ return JTOK_COLON;
+ case ',':
+ raw++;
+ consumed = (raw - rawStart);
+ return JTOK_COMMA;
+
+ case 'n':
+ case 't':
+ case 'f':
+ if (!strncmp(raw, "null", 4)) {
+ raw += 4;
+ consumed = (raw - rawStart);
+ return JTOK_KW_NULL;
+ } else if (!strncmp(raw, "true", 4)) {
+ raw += 4;
+ consumed = (raw - rawStart);
+ return JTOK_KW_TRUE;
+ } else if (!strncmp(raw, "false", 5)) {
+ raw += 5;
+ consumed = (raw - rawStart);
+ return JTOK_KW_FALSE;
+ } else
+ return JTOK_ERR;
+
+ case '-':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9': {
+ // part 1: int
+ std::string numStr;
+
+ const char *first = raw;
+
+ const char *firstDigit = first;
+ if (!json_isdigit(*firstDigit)) firstDigit++;
+ if ((*firstDigit == '0') && json_isdigit(firstDigit[1]))
+ return JTOK_ERR;
- // part 2: frac
- if (raw < end && *raw == '.') {
- numStr += *raw; // copy .
+ numStr += *raw; // copy first char
raw++;
- if (raw >= end || !json_isdigit(*raw))
+ if ((*first == '-') && (raw < end) && (!json_isdigit(*raw)))
return JTOK_ERR;
+
while (raw < end && json_isdigit(*raw)) { // copy digits
numStr += *raw;
raw++;
}
- }
-
- // part 3: exp
- if (raw < end && (*raw == 'e' || *raw == 'E')) {
- numStr += *raw; // copy E
- raw++;
- if (raw < end && (*raw == '-' || *raw == '+')) { // copy +/-
- numStr += *raw;
+ // part 2: frac
+ if (raw < end && *raw == '.') {
+ numStr += *raw; // copy .
raw++;
+
+ if (raw >= end || !json_isdigit(*raw)) return JTOK_ERR;
+ while (raw < end && json_isdigit(*raw)) { // copy digits
+ numStr += *raw;
+ raw++;
+ }
}
- if (raw >= end || !json_isdigit(*raw))
- return JTOK_ERR;
- while (raw < end && json_isdigit(*raw)) { // copy digits
- numStr += *raw;
+ // part 3: exp
+ if (raw < end && (*raw == 'e' || *raw == 'E')) {
+ numStr += *raw; // copy E
raw++;
- }
- }
- tokenVal = numStr;
- consumed = (raw - rawStart);
- return JTOK_NUMBER;
- }
+ if (raw < end && (*raw == '-' || *raw == '+')) { // copy +/-
+ numStr += *raw;
+ raw++;
+ }
- case '"': {
- raw++; // skip "
+ if (raw >= end || !json_isdigit(*raw)) return JTOK_ERR;
+ while (raw < end && json_isdigit(*raw)) { // copy digits
+ numStr += *raw;
+ raw++;
+ }
+ }
- std::string valStr;
- JSONUTF8StringFilter writer(valStr);
+ tokenVal = numStr;
+ consumed = (raw - rawStart);
+ return JTOK_NUMBER;
+ }
- while (true) {
- if (raw >= end || (unsigned char)*raw < 0x20)
- return JTOK_ERR;
+ case '"': {
+ raw++; // skip "
- else if (*raw == '\\') {
- raw++; // skip backslash
+ std::string valStr;
+ JSONUTF8StringFilter writer(valStr);
- if (raw >= end)
+ while (true) {
+ if (raw >= end || (uint8_t)*raw < 0x20)
return JTOK_ERR;
- switch (*raw) {
- case '"': writer.push_back('\"'); break;
- case '\\': writer.push_back('\\'); break;
- case '/': writer.push_back('/'); break;
- case 'b': writer.push_back('\b'); break;
- case 'f': writer.push_back('\f'); break;
- case 'n': writer.push_back('\n'); break;
- case 'r': writer.push_back('\r'); break;
- case 't': writer.push_back('\t'); break;
-
- case 'u': {
- unsigned int codepoint;
- if (raw + 1 + 4 >= end ||
- hatoui(raw + 1, raw + 1 + 4, codepoint) !=
- raw + 1 + 4)
- return JTOK_ERR;
- writer.push_back_u(codepoint);
- raw += 4;
- break;
+ else if (*raw == '\\') {
+ raw++; // skip backslash
+
+ if (raw >= end) return JTOK_ERR;
+
+ switch (*raw) {
+ case '"':
+ writer.push_back('\"');
+ break;
+ case '\\':
+ writer.push_back('\\');
+ break;
+ case '/':
+ writer.push_back('/');
+ break;
+ case 'b':
+ writer.push_back('\b');
+ break;
+ case 'f':
+ writer.push_back('\f');
+ break;
+ case 'n':
+ writer.push_back('\n');
+ break;
+ case 'r':
+ writer.push_back('\r');
+ break;
+ case 't':
+ writer.push_back('\t');
+ break;
+
+ case 'u': {
+ unsigned int codepoint;
+ if (raw + 1 + 4 >= end ||
+ hatoui(raw + 1, raw + 1 + 4, codepoint) !=
+ raw + 1 + 4)
+ return JTOK_ERR;
+ writer.push_back_u(codepoint);
+ raw += 4;
+ break;
+ }
+ default:
+ return JTOK_ERR;
}
- default:
- return JTOK_ERR;
+ raw++; // skip esc'd char
}
- raw++; // skip esc'd char
- }
+ else if (*raw == '"') {
+ raw++; // skip "
+ break; // stop scanning
+ }
- else if (*raw == '"') {
- raw++; // skip "
- break; // stop scanning
+ else {
+ writer.push_back(static_cast<uint8_t>(*raw));
+ raw++;
+ }
}
- else {
- writer.push_back(static_cast<unsigned char>(*raw));
- raw++;
- }
+ if (!writer.finalize()) return JTOK_ERR;
+ tokenVal = valStr;
+ consumed = (raw - rawStart);
+ return JTOK_STRING;
}
- if (!writer.finalize())
+ default:
return JTOK_ERR;
- tokenVal = valStr;
- consumed = (raw - rawStart);
- return JTOK_STRING;
- }
-
- default:
- return JTOK_ERR;
}
}
enum expect_bits : unsigned {
EXP_OBJ_NAME = (1U << 0),
EXP_COLON = (1U << 1),
EXP_ARR_VALUE = (1U << 2),
EXP_VALUE = (1U << 3),
EXP_NOT_VALUE = (1U << 4),
};
#define expect(bit) (expectMask & (EXP_##bit))
#define setExpect(bit) (expectMask |= EXP_##bit)
#define clearExpect(bit) (expectMask &= ~EXP_##bit)
-bool UniValue::read(std::string_view str_in)
-{
+bool UniValue::read(std::string_view str_in) {
clear();
uint32_t expectMask = 0;
- std::vector<UniValue*> stack;
+ std::vector<UniValue *> stack;
std::string tokenVal;
unsigned int consumed;
enum jtokentype tok = JTOK_NONE;
enum jtokentype last_tok = JTOK_NONE;
- const char* raw{str_in.data()};
- const char* end{raw + str_in.size()};
+ const char *raw{str_in.data()};
+ const char *end{raw + str_in.size()};
do {
last_tok = tok;
tok = getJsonToken(tokenVal, consumed, raw, end);
- if (tok == JTOK_NONE || tok == JTOK_ERR)
- goto return_fail;
+ if (tok == JTOK_NONE || tok == JTOK_ERR) goto return_fail;
raw += consumed;
- bool isValueOpen = jsonTokenIsValue(tok) ||
- tok == JTOK_OBJ_OPEN || tok == JTOK_ARR_OPEN;
+ bool isValueOpen = jsonTokenIsValue(tok) || tok == JTOK_OBJ_OPEN ||
+ tok == JTOK_ARR_OPEN;
if (expect(VALUE)) {
- if (!isValueOpen)
- goto return_fail;
+ if (!isValueOpen) goto return_fail;
clearExpect(VALUE);
} else if (expect(ARR_VALUE)) {
bool isArrValue = isValueOpen || (tok == JTOK_ARR_CLOSE);
- if (!isArrValue)
- goto return_fail;
+ if (!isArrValue) goto return_fail;
clearExpect(ARR_VALUE);
} else if (expect(OBJ_NAME)) {
bool isObjName = (tok == JTOK_OBJ_CLOSE || tok == JTOK_STRING);
- if (!isObjName)
- goto return_fail;
+ if (!isObjName) goto return_fail;
} else if (expect(COLON)) {
- if (tok != JTOK_COLON)
- goto return_fail;
+ if (tok != JTOK_COLON) goto return_fail;
clearExpect(COLON);
} else if (!expect(COLON) && (tok == JTOK_COLON)) {
goto return_fail;
}
if (expect(NOT_VALUE)) {
- if (isValueOpen)
- goto return_fail;
+ if (isValueOpen) goto return_fail;
clearExpect(NOT_VALUE);
}
switch (tok) {
+ case JTOK_OBJ_OPEN:
+ case JTOK_ARR_OPEN: {
+ VType utyp = (tok == JTOK_OBJ_OPEN ? VOBJ : VARR);
+ if (!stack.size()) {
+ if (utyp == VOBJ)
+ setObject();
+ else
+ setArray();
+ stack.push_back(this);
+ } else {
+ UniValue tmpVal(utyp);
+ UniValue *top = stack.back();
+ top->values.push_back(tmpVal);
+
+ UniValue *newTop = &(top->values.back());
+ stack.push_back(newTop);
+ }
+
+ if (stack.size() > MAX_JSON_DEPTH) goto return_fail;
- case JTOK_OBJ_OPEN:
- case JTOK_ARR_OPEN: {
- VType utyp = (tok == JTOK_OBJ_OPEN ? VOBJ : VARR);
- if (!stack.size()) {
if (utyp == VOBJ)
- setObject();
+ setExpect(OBJ_NAME);
else
- setArray();
- stack.push_back(this);
- } else {
- UniValue tmpVal(utyp);
- UniValue *top = stack.back();
- top->values.push_back(tmpVal);
-
- UniValue *newTop = &(top->values.back());
- stack.push_back(newTop);
- }
-
- if (stack.size() > MAX_JSON_DEPTH)
- goto return_fail;
-
- if (utyp == VOBJ)
- setExpect(OBJ_NAME);
- else
- setExpect(ARR_VALUE);
- break;
+ setExpect(ARR_VALUE);
+ break;
}
- case JTOK_OBJ_CLOSE:
- case JTOK_ARR_CLOSE: {
- if (!stack.size() || (last_tok == JTOK_COMMA))
- goto return_fail;
+ case JTOK_OBJ_CLOSE:
+ case JTOK_ARR_CLOSE: {
+ if (!stack.size() || (last_tok == JTOK_COMMA)) goto return_fail;
- VType utyp = (tok == JTOK_OBJ_CLOSE ? VOBJ : VARR);
- UniValue *top = stack.back();
- if (utyp != top->getType())
- goto return_fail;
+ VType utyp = (tok == JTOK_OBJ_CLOSE ? VOBJ : VARR);
+ UniValue *top = stack.back();
+ if (utyp != top->getType()) goto return_fail;
- stack.pop_back();
- clearExpect(OBJ_NAME);
- setExpect(NOT_VALUE);
- break;
+ stack.pop_back();
+ clearExpect(OBJ_NAME);
+ setExpect(NOT_VALUE);
+ break;
}
- case JTOK_COLON: {
- if (!stack.size())
- goto return_fail;
+ case JTOK_COLON: {
+ if (!stack.size()) goto return_fail;
- UniValue *top = stack.back();
- if (top->getType() != VOBJ)
- goto return_fail;
+ UniValue *top = stack.back();
+ if (top->getType() != VOBJ) goto return_fail;
- setExpect(VALUE);
- break;
+ setExpect(VALUE);
+ break;
}
- case JTOK_COMMA: {
- if (!stack.size() ||
- (last_tok == JTOK_COMMA) || (last_tok == JTOK_ARR_OPEN))
- goto return_fail;
+ case JTOK_COMMA: {
+ if (!stack.size() || (last_tok == JTOK_COMMA) ||
+ (last_tok == JTOK_ARR_OPEN))
+ goto return_fail;
- UniValue *top = stack.back();
- if (top->getType() == VOBJ)
- setExpect(OBJ_NAME);
- else
- setExpect(ARR_VALUE);
- break;
+ UniValue *top = stack.back();
+ if (top->getType() == VOBJ)
+ setExpect(OBJ_NAME);
+ else
+ setExpect(ARR_VALUE);
+ break;
}
- case JTOK_KW_NULL:
- case JTOK_KW_TRUE:
- case JTOK_KW_FALSE: {
- UniValue tmpVal;
- switch (tok) {
case JTOK_KW_NULL:
- // do nothing more
- break;
case JTOK_KW_TRUE:
- tmpVal.setBool(true);
- break;
- case JTOK_KW_FALSE:
- tmpVal.setBool(false);
- break;
- default: /* impossible */ break;
- }
-
- if (!stack.size()) {
- *this = tmpVal;
- break;
- }
+ case JTOK_KW_FALSE: {
+ UniValue tmpVal;
+ switch (tok) {
+ case JTOK_KW_NULL:
+ // do nothing more
+ break;
+ case JTOK_KW_TRUE:
+ tmpVal.setBool(true);
+ break;
+ case JTOK_KW_FALSE:
+ tmpVal.setBool(false);
+ break;
+ default: /* impossible */
+ break;
+ }
- UniValue *top = stack.back();
- top->values.push_back(tmpVal);
+ if (!stack.size()) {
+ *this = tmpVal;
+ break;
+ }
- setExpect(NOT_VALUE);
- break;
- }
+ UniValue *top = stack.back();
+ top->values.push_back(tmpVal);
- case JTOK_NUMBER: {
- UniValue tmpVal(VNUM, tokenVal);
- if (!stack.size()) {
- *this = tmpVal;
+ setExpect(NOT_VALUE);
break;
}
- UniValue *top = stack.back();
- top->values.push_back(tmpVal);
-
- setExpect(NOT_VALUE);
- break;
- }
-
- case JTOK_STRING: {
- if (expect(OBJ_NAME)) {
- UniValue *top = stack.back();
- top->keys.push_back(tokenVal);
- clearExpect(OBJ_NAME);
- setExpect(COLON);
- } else {
- UniValue tmpVal(VSTR, tokenVal);
+ case JTOK_NUMBER: {
+ UniValue tmpVal(VNUM, tokenVal);
if (!stack.size()) {
*this = tmpVal;
break;
}
+
UniValue *top = stack.back();
top->values.push_back(tmpVal);
+
+ setExpect(NOT_VALUE);
+ break;
}
- setExpect(NOT_VALUE);
- break;
+ case JTOK_STRING: {
+ if (expect(OBJ_NAME)) {
+ UniValue *top = stack.back();
+ top->keys.push_back(tokenVal);
+ clearExpect(OBJ_NAME);
+ setExpect(COLON);
+ } else {
+ UniValue tmpVal(VSTR, tokenVal);
+ if (!stack.size()) {
+ *this = tmpVal;
+ break;
+ }
+ UniValue *top = stack.back();
+ top->values.push_back(tmpVal);
+ }
+
+ setExpect(NOT_VALUE);
+ break;
}
- default:
- goto return_fail;
+ default:
+ goto return_fail;
}
- } while (!stack.empty ());
+ } 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;
+ if (tok != JTOK_NONE) goto return_fail;
return true;
return_fail:
clear();
return false;
}
-
diff --git a/src/univalue/lib/univalue_write.cpp b/src/univalue/lib/univalue_write.cpp
index ee736274b..8d7c12707 100644
--- a/src/univalue/lib/univalue_write.cpp
+++ b/src/univalue/lib/univalue_write.cpp
@@ -1,163 +1,164 @@
// Copyright 2014 BitPay Inc.
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.
#include <univalue.h>
#include <univalue_escapes.h>
#include <cstddef>
#include <string>
#include <utility>
namespace {
struct UniValueStreamWriter {
std::string str;
- UniValueStreamWriter() {
- str.reserve(1024);
- }
+ UniValueStreamWriter() { str.reserve(1024); }
std::string getString() {
#if __cplusplus >= 201103L
return std::move(str);
#else
std::string ret;
std::swap(ret, str);
return ret;
#endif
}
- void put(char c) {
- str.push_back(c);
- }
- void put(char c, size_t nFill) {
- str.append(nFill, c);
- }
- void write(const char *s) {
- str.append(s);
- }
- void write(const std::string &s) {
- str.append(s);
- }
+ void put(char c) { str.push_back(c); }
+ void put(char c, size_t nFill) { str.append(nFill, c); }
+ void write(const char *s) { str.append(s); }
+ void write(const std::string &s) { str.append(s); }
void indentStr(unsigned int prettyIndent, unsigned int indentLevel) {
put(' ', prettyIndent * indentLevel);
}
void escapeJson(const std::string &inS);
- void writeAny(unsigned int prettyIndent, unsigned int indentLevel, const UniValue &obj);
- void writeArray(unsigned int prettyIndent, unsigned int indentLevel, const UniValue &obj);
- void writeObject(unsigned int prettyIndent, unsigned int indentLevel, const UniValue &obj);
+ void writeAny(unsigned int prettyIndent, unsigned int indentLevel,
+ const UniValue &obj);
+ void writeArray(unsigned int prettyIndent, unsigned int indentLevel,
+ const UniValue &obj);
+ void writeObject(unsigned int prettyIndent, unsigned int indentLevel,
+ const UniValue &obj);
};
void UniValueStreamWriter::escapeJson(const std::string &inS) {
size_t len = inS.length();
for (size_t i = 0; i < len; i++) {
const char ch = inS[i];
- const char * const escStr = escapes[uint8_t(ch)];
+ const char *const escStr = escapes[uint8_t(ch)];
if (escStr) {
write(escStr);
} else {
put(ch);
}
}
}
-void UniValueStreamWriter::writeAny(unsigned int prettyIndent, unsigned int indentLevel, const UniValue &obj) {
+void UniValueStreamWriter::writeAny(unsigned int prettyIndent,
+ unsigned int indentLevel,
+ const UniValue &obj) {
unsigned int modIndent = indentLevel;
if (modIndent == 0) {
modIndent = 1;
}
switch (obj.typ) {
- case UniValue::VNULL:
- write("null");
- break;
- case UniValue::VOBJ:
- writeObject(prettyIndent, modIndent, obj);
- break;
- case UniValue::VARR:
- writeArray(prettyIndent, modIndent, obj);
- break;
- case UniValue::VSTR:
- put('"');
- escapeJson(obj.val);
- put('"');
- break;
- case UniValue::VNUM:
- write(obj.val);
- break;
- case UniValue::VBOOL:
- write(obj.val == "1" ? "true" : "false");
- break;
+ case UniValue::VNULL:
+ write("null");
+ break;
+ case UniValue::VOBJ:
+ writeObject(prettyIndent, modIndent, obj);
+ break;
+ case UniValue::VARR:
+ writeArray(prettyIndent, modIndent, obj);
+ break;
+ case UniValue::VSTR:
+ put('"');
+ escapeJson(obj.val);
+ put('"');
+ break;
+ case UniValue::VNUM:
+ write(obj.val);
+ break;
+ case UniValue::VBOOL:
+ write(obj.val == "1" ? "true" : "false");
+ break;
}
}
-void UniValueStreamWriter::writeArray(unsigned int prettyIndent, unsigned int indentLevel, const UniValue &obj) {
+void UniValueStreamWriter::writeArray(unsigned int prettyIndent,
+ unsigned int indentLevel,
+ const UniValue &obj) {
put('[');
if (prettyIndent) {
put('\n');
}
const size_t nValues = obj.values.size();
for (size_t i = 0; i < nValues; ++i) {
if (prettyIndent) {
indentStr(prettyIndent, indentLevel);
}
writeAny(prettyIndent, indentLevel + 1, obj.values[i]);
if (i != nValues - 1) {
put(',');
}
if (prettyIndent) {
put('\n');
}
}
if (prettyIndent) {
indentStr(prettyIndent, indentLevel - 1);
}
put(']');
}
-void UniValueStreamWriter::writeObject(unsigned int prettyIndent, unsigned int indentLevel, const UniValue &obj) {
+void UniValueStreamWriter::writeObject(unsigned int prettyIndent,
+ unsigned int indentLevel,
+ const UniValue &obj) {
put('{');
if (prettyIndent) {
put('\n');
}
// Note: if typ == VOBJ, then keys.size() == values.size() always, so we can
- // use the non-bounds-checking operator[]() for both keys and values here safely.
+ // use the non-bounds-checking operator[]() for both keys and values here
+ // safely.
const size_t nItems = obj.keys.size();
for (size_t i = 0; i < nItems; ++i) {
if (prettyIndent) {
indentStr(prettyIndent, indentLevel);
}
put('"');
escapeJson(obj.keys[i]);
write("\":");
if (prettyIndent) {
put(' ');
}
writeAny(prettyIndent, indentLevel + 1, obj.values[i]);
if (i != nItems - 1) {
put(',');
}
if (prettyIndent) {
put('\n');
}
}
if (prettyIndent) {
indentStr(prettyIndent, indentLevel - 1);
}
put('}');
}
-}
+} // namespace
-std::string UniValue::write(unsigned int prettyIndent, unsigned int indentLevel) const {
+std::string UniValue::write(unsigned int prettyIndent,
+ unsigned int indentLevel) const {
UniValueStreamWriter ss;
ss.writeAny(prettyIndent, indentLevel, *this);
return ss.getString();
}
diff --git a/src/univalue/test/object.cpp b/src/univalue/test/object.cpp
index e72cc90fa..51e334ba8 100644
--- a/src/univalue/test/object.cpp
+++ b/src/univalue/test/object.cpp
@@ -1,472 +1,465 @@
// Copyright (c) 2014 BitPay Inc.
// Copyright (c) 2014-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.
#include <univalue.h>
#include <cassert>
#include <cstdint>
#include <map>
#include <memory>
#include <stdexcept>
#include <string>
#include <string_view>
#include <vector>
#define BOOST_CHECK(expr) assert(expr)
#define BOOST_CHECK_EQUAL(v1, v2) assert((v1) == (v2))
-#define BOOST_CHECK_THROW(stmt, excMatch) { \
- try { \
- (stmt); \
- assert(0 && "No exception caught"); \
- } catch (excMatch & e) { \
- } catch (...) { \
- assert(0 && "Wrong exception caught"); \
- } \
+#define BOOST_CHECK_THROW(stmt, excMatch) \
+ { \
+ try { \
+ (stmt); \
+ assert(0 && "No exception caught"); \
+ } catch (excMatch & e) { \
+ } catch (...) { \
+ assert(0 && "Wrong exception caught"); \
+ } \
}
-#define BOOST_CHECK_NO_THROW(stmt) { \
- try { \
- (stmt); \
- } catch (...) { \
- assert(0); \
- } \
+#define BOOST_CHECK_NO_THROW(stmt) \
+ { \
+ try { \
+ (stmt); \
+ } catch (...) { \
+ assert(0); \
+ } \
}
-void univalue_constructor()
-{
+void univalue_constructor() {
UniValue v1;
BOOST_CHECK(v1.isNull());
UniValue v2(UniValue::VSTR);
BOOST_CHECK(v2.isStr());
UniValue v3(UniValue::VSTR, "foo");
BOOST_CHECK(v3.isStr());
BOOST_CHECK_EQUAL(v3.getValStr(), "foo");
UniValue numTest;
numTest.setNumStr("82");
BOOST_CHECK(numTest.isNum());
BOOST_CHECK_EQUAL(numTest.getValStr(), "82");
uint64_t vu64 = 82;
UniValue v4(vu64);
BOOST_CHECK(v4.isNum());
BOOST_CHECK_EQUAL(v4.getValStr(), "82");
int64_t vi64 = -82;
UniValue v5(vi64);
BOOST_CHECK(v5.isNum());
BOOST_CHECK_EQUAL(v5.getValStr(), "-82");
int vi = -688;
UniValue v6(vi);
BOOST_CHECK(v6.isNum());
BOOST_CHECK_EQUAL(v6.getValStr(), "-688");
double vd = -7.21;
UniValue v7(vd);
BOOST_CHECK(v7.isNum());
BOOST_CHECK_EQUAL(v7.getValStr(), "-7.21");
std::string vs("yawn");
UniValue v8(vs);
BOOST_CHECK(v8.isStr());
BOOST_CHECK_EQUAL(v8.getValStr(), "yawn");
const char *vcs = "zappa";
UniValue v9(vcs);
BOOST_CHECK(v9.isStr());
BOOST_CHECK_EQUAL(v9.getValStr(), "zappa");
}
-void univalue_push_throw()
-{
+void univalue_push_throw() {
UniValue j;
BOOST_CHECK_THROW(j.push_back(1), std::runtime_error);
BOOST_CHECK_THROW(j.push_backV({1}), std::runtime_error);
BOOST_CHECK_THROW(j.pushKVEnd("k", 1), std::runtime_error);
BOOST_CHECK_THROW(j.pushKV("k", 1), std::runtime_error);
BOOST_CHECK_THROW(j.pushKVs({}), std::runtime_error);
}
-void univalue_typecheck()
-{
+void univalue_typecheck() {
UniValue v1;
v1.setNumStr("1");
BOOST_CHECK(v1.isNum());
BOOST_CHECK_THROW(v1.get_bool(), std::runtime_error);
{
UniValue v_negative;
v_negative.setNumStr("-1");
BOOST_CHECK_THROW(v_negative.getInt<uint8_t>(), std::runtime_error);
BOOST_CHECK_EQUAL(v_negative.getInt<int8_t>(), -1);
}
UniValue v2;
v2.setBool(true);
BOOST_CHECK_EQUAL(v2.get_bool(), true);
BOOST_CHECK_THROW(v2.getInt<int>(), std::runtime_error);
UniValue v3;
v3.setNumStr("32482348723847471234");
BOOST_CHECK_THROW(v3.getInt<int64_t>(), std::runtime_error);
v3.setNumStr("1000");
BOOST_CHECK_EQUAL(v3.getInt<int64_t>(), 1000);
UniValue v4;
v4.setNumStr("2147483648");
BOOST_CHECK_EQUAL(v4.getInt<int64_t>(), 2147483648);
BOOST_CHECK_THROW(v4.getInt<int>(), std::runtime_error);
v4.setNumStr("1000");
BOOST_CHECK_EQUAL(v4.getInt<int>(), 1000);
BOOST_CHECK_THROW(v4.get_str(), std::runtime_error);
BOOST_CHECK_EQUAL(v4.get_real(), 1000);
BOOST_CHECK_THROW(v4.get_array(), std::runtime_error);
BOOST_CHECK_THROW(v4.getKeys(), std::runtime_error);
BOOST_CHECK_THROW(v4.getValues(), std::runtime_error);
BOOST_CHECK_THROW(v4.get_obj(), std::runtime_error);
UniValue v5;
BOOST_CHECK(v5.read("[true, 10]"));
BOOST_CHECK_NO_THROW(v5.get_array());
std::vector<UniValue> vals = v5.getValues();
BOOST_CHECK_THROW(vals[0].getInt<int>(), std::runtime_error);
BOOST_CHECK_EQUAL(vals[0].get_bool(), true);
BOOST_CHECK_EQUAL(vals[1].getInt<int>(), 10);
BOOST_CHECK_THROW(vals[1].get_bool(), std::runtime_error);
}
-void univalue_set()
-{
+void univalue_set() {
UniValue v(UniValue::VSTR, "foo");
v.clear();
BOOST_CHECK(v.isNull());
BOOST_CHECK_EQUAL(v.getValStr(), "");
v.setObject();
BOOST_CHECK(v.isObject());
BOOST_CHECK_EQUAL(v.size(), 0);
BOOST_CHECK_EQUAL(v.getType(), UniValue::VOBJ);
BOOST_CHECK(v.empty());
v.setArray();
BOOST_CHECK(v.isArray());
BOOST_CHECK_EQUAL(v.size(), 0);
v.setStr("zum");
BOOST_CHECK(v.isStr());
BOOST_CHECK_EQUAL(v.getValStr(), "zum");
{
std::string_view sv{"ab\0c", 4};
UniValue j{sv};
BOOST_CHECK(j.isStr());
BOOST_CHECK_EQUAL(j.getValStr(), sv);
BOOST_CHECK_EQUAL(j.write(), "\"ab\\u0000c\"");
}
v.setFloat(-1.01);
BOOST_CHECK(v.isNum());
BOOST_CHECK_EQUAL(v.getValStr(), "-1.01");
v.setInt(int{1023});
BOOST_CHECK(v.isNum());
BOOST_CHECK_EQUAL(v.getValStr(), "1023");
v.setInt(int64_t{-1023LL});
BOOST_CHECK(v.isNum());
BOOST_CHECK_EQUAL(v.getValStr(), "-1023");
v.setInt(uint64_t{1023ULL});
BOOST_CHECK(v.isNum());
BOOST_CHECK_EQUAL(v.getValStr(), "1023");
v.setNumStr("-688");
BOOST_CHECK(v.isNum());
BOOST_CHECK_EQUAL(v.getValStr(), "-688");
v.setBool(false);
BOOST_CHECK_EQUAL(v.isBool(), true);
BOOST_CHECK_EQUAL(v.isTrue(), false);
BOOST_CHECK_EQUAL(v.isFalse(), true);
BOOST_CHECK_EQUAL(v.get_bool(), false);
v.setBool(true);
BOOST_CHECK_EQUAL(v.isBool(), true);
BOOST_CHECK_EQUAL(v.isTrue(), true);
BOOST_CHECK_EQUAL(v.isFalse(), false);
BOOST_CHECK_EQUAL(v.get_bool(), true);
BOOST_CHECK_THROW(v.setNumStr("zombocom"), std::runtime_error);
v.setNull();
BOOST_CHECK(v.isNull());
}
-void univalue_array()
-{
+void univalue_array() {
UniValue arr(UniValue::VARR);
arr.reserve(9);
UniValue v((int64_t)1023LL);
arr.push_back(v);
std::string vStr("zippy");
arr.push_back(vStr);
const char *s = "pippy";
arr.push_back(s);
std::vector<UniValue> vec;
v.setStr("boing");
vec.push_back(v);
v.setStr("going");
vec.push_back(v);
arr.push_backV(vec);
arr.push_back(uint64_t{400ULL});
arr.push_back(int64_t{-400LL});
arr.push_back(int{-401});
arr.push_back(-40.1);
arr.push_back(true);
BOOST_CHECK_EQUAL(arr.empty(), false);
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(), "");
arr.clear();
BOOST_CHECK(arr.empty());
BOOST_CHECK_EQUAL(arr.size(), 0);
}
-void univalue_object()
-{
+void univalue_object() {
UniValue obj(UniValue::VOBJ);
std::string strKey, strVal;
UniValue v;
obj.reserve(11);
strKey = "age";
v.setInt(100);
obj.pushKV(strKey, v);
strKey = "first";
strVal = "John";
obj.pushKV(strKey, strVal);
strKey = "last";
- const char* cVal = "Smith";
+ const char *cVal = "Smith";
obj.pushKV(strKey, cVal);
strKey = "distance";
obj.pushKV(strKey, int64_t{25});
strKey = "time";
obj.pushKV(strKey, uint64_t{3600});
strKey = "calories";
obj.pushKV(strKey, int{12});
strKey = "temperature";
obj.pushKV(strKey, double{90.012});
strKey = "moon";
obj.pushKV(strKey, true);
strKey = "spoon";
obj.pushKV(strKey, false);
UniValue obj2(UniValue::VOBJ);
obj2.pushKV("cat1", 9000);
obj2.pushKV("cat2", 12345);
obj.pushKVs(obj2);
BOOST_CHECK_EQUAL(obj.empty(), false);
BOOST_CHECK_EQUAL(obj.size(), 11);
BOOST_CHECK_EQUAL(obj["age"].getValStr(), "100");
BOOST_CHECK_EQUAL(obj["first"].getValStr(), "John");
BOOST_CHECK_EQUAL(obj["last"].getValStr(), "Smith");
BOOST_CHECK_EQUAL(obj["distance"].getValStr(), "25");
BOOST_CHECK_EQUAL(obj["time"].getValStr(), "3600");
BOOST_CHECK_EQUAL(obj["calories"].getValStr(), "12");
BOOST_CHECK_EQUAL(obj["temperature"].getValStr(), "90.012");
BOOST_CHECK_EQUAL(obj["moon"].getValStr(), "1");
BOOST_CHECK_EQUAL(obj["spoon"].getValStr(), "");
BOOST_CHECK_EQUAL(obj["cat1"].getValStr(), "9000");
BOOST_CHECK_EQUAL(obj["cat2"].getValStr(), "12345");
BOOST_CHECK_EQUAL(obj["nyuknyuknyuk"].getValStr(), "");
BOOST_CHECK(obj.exists("age"));
BOOST_CHECK(obj.exists("first"));
BOOST_CHECK(obj.exists("last"));
BOOST_CHECK(obj.exists("distance"));
BOOST_CHECK(obj.exists("time"));
BOOST_CHECK(obj.exists("calories"));
BOOST_CHECK(obj.exists("temperature"));
BOOST_CHECK(obj.exists("moon"));
BOOST_CHECK(obj.exists("spoon"));
BOOST_CHECK(obj.exists("cat1"));
BOOST_CHECK(obj.exists("cat2"));
BOOST_CHECK(!obj.exists("nyuknyuknyuk"));
std::map<std::string, UniValue::VType> objTypes;
objTypes["age"] = UniValue::VNUM;
objTypes["first"] = UniValue::VSTR;
objTypes["last"] = UniValue::VSTR;
objTypes["distance"] = UniValue::VNUM;
objTypes["time"] = UniValue::VNUM;
objTypes["calories"] = UniValue::VNUM;
objTypes["temperature"] = UniValue::VNUM;
objTypes["moon"] = UniValue::VBOOL;
objTypes["spoon"] = UniValue::VBOOL;
objTypes["cat1"] = UniValue::VNUM;
objTypes["cat2"] = UniValue::VNUM;
BOOST_CHECK(obj.checkObject(objTypes));
objTypes["cat2"] = UniValue::VSTR;
BOOST_CHECK(!obj.checkObject(objTypes));
obj.clear();
BOOST_CHECK(obj.empty());
BOOST_CHECK_EQUAL(obj.size(), 0);
BOOST_CHECK_EQUAL(obj.getType(), UniValue::VNULL);
obj.setObject();
UniValue uv;
uv.setInt(42);
obj.pushKVEnd("age", uv);
BOOST_CHECK_EQUAL(obj.size(), 1);
BOOST_CHECK_EQUAL(obj["age"].getValStr(), "42");
uv.setInt(43);
obj.pushKV("age", uv);
BOOST_CHECK_EQUAL(obj.size(), 1);
BOOST_CHECK_EQUAL(obj["age"].getValStr(), "43");
obj.pushKV("name", "foo bar");
- std::map<std::string,UniValue> kv;
+ std::map<std::string, UniValue> kv;
obj.getObjMap(kv);
BOOST_CHECK_EQUAL(kv["age"].getValStr(), "43");
BOOST_CHECK_EQUAL(kv["name"].getValStr(), "foo bar");
-
}
-static const char *json1 =
-"[1.10000000,{\"key1\":\"str\\u0000\",\"key2\":800,\"key3\":{\"name\":\"martian http://test.com\"}}]";
+static const char *json1 = "[1.10000000,{\"key1\":\"str\\u0000\",\"key2\":800,"
+ "\"key3\":{\"name\":\"martian http://test.com\"}}]";
-void univalue_readwrite()
-{
+void univalue_readwrite() {
UniValue v;
BOOST_CHECK(v.read(json1));
std::string strJson1(json1);
BOOST_CHECK(v.read(strJson1));
BOOST_CHECK(v.isArray());
BOOST_CHECK_EQUAL(v.size(), 2);
BOOST_CHECK_EQUAL(v[0].getValStr(), "1.10000000");
UniValue obj = v[1];
BOOST_CHECK(obj.isObject());
BOOST_CHECK_EQUAL(obj.size(), 3);
BOOST_CHECK(obj["key1"].isStr());
std::string correctValue("str");
correctValue.push_back('\0');
BOOST_CHECK_EQUAL(obj["key1"].getValStr(), correctValue);
BOOST_CHECK(obj["key2"].isNum());
BOOST_CHECK_EQUAL(obj["key2"].getValStr(), "800");
BOOST_CHECK(obj["key3"].isObject());
BOOST_CHECK_EQUAL(strJson1, v.write());
// Valid
BOOST_CHECK(v.read("1.0") && (v.get_real() == 1.0));
BOOST_CHECK(v.read("true") && v.get_bool());
BOOST_CHECK(v.read("[false]") && !v[0].get_bool());
BOOST_CHECK(v.read("{\"a\": true}") && v["a"].get_bool());
BOOST_CHECK(v.read("{\"1\": \"true\"}") && (v["1"].get_str() == "true"));
// Valid, with leading or trailing whitespace
BOOST_CHECK(v.read(" 1.0") && (v.get_real() == 1.0));
BOOST_CHECK(v.read("1.0 ") && (v.get_real() == 1.0));
BOOST_CHECK(v.read("0.00000000000000000000000000000000000001e+30 "));
- //should fail, missing leading 0, therefore invalid JSON
+ // should fail, missing leading 0, therefore invalid JSON
BOOST_CHECK(!v.read(".19e-6"));
// Invalid, initial garbage
BOOST_CHECK(!v.read("[1.0"));
BOOST_CHECK(!v.read("a1.0"));
// Invalid, trailing garbage
BOOST_CHECK(!v.read("1.0sds"));
BOOST_CHECK(!v.read("1.0]"));
// Invalid, keys have to be names
BOOST_CHECK(!v.read("{1: \"true\"}"));
BOOST_CHECK(!v.read("{true: 1}"));
BOOST_CHECK(!v.read("{[1]: 1}"));
BOOST_CHECK(!v.read("{{\"a\": \"a\"}: 1}"));
// BTC addresses should fail parsing
BOOST_CHECK(!v.read("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"));
BOOST_CHECK(!v.read("3J98t1WpEZ73CNmQviecrnyiWrnqRhWNL"));
/* Check for (correctly reporting) a parsing error if the initial
JSON construct is followed by more stuff. Note that whitespace
is, of course, exempt. */
BOOST_CHECK(v.read(" {}\n "));
BOOST_CHECK(v.isObject());
BOOST_CHECK(v.read(" []\n "));
BOOST_CHECK(v.isArray());
BOOST_CHECK(!v.read("@{}"));
BOOST_CHECK(!v.read("{} garbage"));
BOOST_CHECK(!v.read("[]{}"));
BOOST_CHECK(!v.read("{}[]"));
BOOST_CHECK(!v.read("{} 42"));
}
-int main(int argc, char* argv[])
-{
+int main(int argc, char *argv[]) {
univalue_constructor();
univalue_push_throw();
univalue_typecheck();
univalue_set();
univalue_array();
univalue_object();
univalue_readwrite();
return 0;
}
diff --git a/src/univalue/test/test_json.cpp b/src/univalue/test/test_json.cpp
index f8c10238d..deabfa3cf 100644
--- a/src/univalue/test/test_json.cpp
+++ b/src/univalue/test/test_json.cpp
@@ -1,26 +1,25 @@
// Test program that can be called by the JSON test suite at
// https://github.com/nst/JSONTestSuite.
//
// 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>
using namespace std;
-int main (int argc, char *argv[])
-{
+int main(int argc, char *argv[]) {
UniValue val;
if (val.read(string(istreambuf_iterator<char>(cin),
istreambuf_iterator<char>()))) {
cout << val.write(1 /* prettyIndent */, 4 /* indentLevel */) << endl;
return 0;
} else {
cerr << "JSON Parse Error." << endl;
return 1;
}
}
diff --git a/src/univalue/test/unitester.cpp b/src/univalue/test/unitester.cpp
index d27e647e5..b9ff91d6d 100644
--- a/src/univalue/test/unitester.cpp
+++ b/src/univalue/test/unitester.cpp
@@ -1,170 +1,135 @@
// Copyright 2014 BitPay Inc.
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.
#include <univalue.h>
#include <cassert>
#include <cstdio>
#include <string>
#ifndef JSON_TEST_SRC
#error JSON_TEST_SRC must point to test source directory
#endif
std::string srcdir(JSON_TEST_SRC);
-static std::string rtrim(std::string s)
-{
- s.erase(s.find_last_not_of(" \n\r\t")+1);
+static std::string rtrim(std::string s) {
+ s.erase(s.find_last_not_of(" \n\r\t") + 1);
return s;
}
-static void runtest(std::string filename, const std::string& jdata)
-{
- std::string prefix = filename.substr(0, 4);
+static void runtest(std::string filename, const std::string &jdata) {
+ std::string prefix = filename.substr(0, 4);
- bool wantPass = (prefix == "pass") || (prefix == "roun");
- bool wantFail = (prefix == "fail");
- bool wantRoundTrip = (prefix == "roun");
- assert(wantPass || wantFail);
+ bool wantPass = (prefix == "pass") || (prefix == "roun");
+ bool wantFail = (prefix == "fail");
+ bool wantRoundTrip = (prefix == "roun");
+ assert(wantPass || wantFail);
- UniValue val;
- bool testResult = val.read(jdata);
+ UniValue val;
+ bool testResult = val.read(jdata);
- if (wantPass) {
- assert(testResult == true);
- } else {
- assert(testResult == false);
- }
+ if (wantPass) {
+ assert(testResult == true);
+ } else {
+ assert(testResult == false);
+ }
- if (wantRoundTrip) {
- std::string odata = val.write(0, 0);
- assert(odata == rtrim(jdata));
- }
+ if (wantRoundTrip) {
+ std::string odata = val.write(0, 0);
+ assert(odata == rtrim(jdata));
+ }
}
-static void runtest_file(const char *filename_)
-{
- std::string basename(filename_);
- std::string filename = srcdir + "/" + basename;
- FILE *f = fopen(filename.c_str(), "r");
- assert(f != nullptr);
+static void runtest_file(const char *filename_) {
+ std::string basename(filename_);
+ std::string filename = srcdir + "/" + basename;
+ FILE *f = fopen(filename.c_str(), "r");
+ assert(f != nullptr);
- std::string jdata;
+ std::string jdata;
- char buf[4096];
- while (!feof(f)) {
- int bread = fread(buf, 1, sizeof(buf), f);
- assert(!ferror(f));
+ char buf[4096];
+ while (!feof(f)) {
+ int bread = fread(buf, 1, sizeof(buf), f);
+ assert(!ferror(f));
- std::string s(buf, bread);
- jdata += s;
- }
+ std::string s(buf, bread);
+ jdata += s;
+ }
- assert(!ferror(f));
- fclose(f);
+ assert(!ferror(f));
+ fclose(f);
- runtest(basename, jdata);
+ runtest(basename, jdata);
}
static const char *filenames[] = {
- "fail10.json",
- "fail11.json",
- "fail12.json",
- "fail13.json",
- "fail14.json",
- "fail15.json",
- "fail16.json",
- "fail17.json",
- //"fail18.json", // investigate
- "fail19.json",
- "fail1.json",
- "fail20.json",
- "fail21.json",
- "fail22.json",
- "fail23.json",
- "fail24.json",
- "fail25.json",
- "fail26.json",
- "fail27.json",
- "fail28.json",
- "fail29.json",
- "fail2.json",
- "fail30.json",
- "fail31.json",
- "fail32.json",
- "fail33.json",
- "fail34.json",
- "fail35.json",
- "fail36.json",
- "fail37.json",
- "fail38.json", // invalid unicode: only first half of surrogate pair
- "fail39.json", // invalid unicode: only second half of surrogate pair
- "fail40.json", // invalid unicode: broken UTF-8
- "fail41.json", // invalid unicode: unfinished UTF-8
- "fail42.json", // valid json with garbage following a nul byte
- "fail44.json", // unterminated string
- "fail45.json", // nested beyond max depth
- "fail3.json",
- "fail4.json", // extra comma
- "fail5.json",
- "fail6.json",
- "fail7.json",
- "fail8.json",
- "fail9.json", // extra comma
- "pass1.json",
- "pass2.json",
- "pass3.json",
- "pass4.json",
- "round1.json", // round-trip test
- "round2.json", // unicode
- "round3.json", // bare string
- "round4.json", // bare number
- "round5.json", // bare true
- "round6.json", // bare false
- "round7.json", // bare null
+ "fail10.json", "fail11.json", "fail12.json", "fail13.json", "fail14.json",
+ "fail15.json", "fail16.json", "fail17.json",
+ //"fail18.json", // investigate
+ "fail19.json", "fail1.json", "fail20.json", "fail21.json", "fail22.json",
+ "fail23.json", "fail24.json", "fail25.json", "fail26.json", "fail27.json",
+ "fail28.json", "fail29.json", "fail2.json", "fail30.json", "fail31.json",
+ "fail32.json", "fail33.json", "fail34.json", "fail35.json", "fail36.json",
+ "fail37.json",
+ "fail38.json", // invalid unicode: only first half of surrogate pair
+ "fail39.json", // invalid unicode: only second half of surrogate pair
+ "fail40.json", // invalid unicode: broken UTF-8
+ "fail41.json", // invalid unicode: unfinished UTF-8
+ "fail42.json", // valid json with garbage following a nul byte
+ "fail44.json", // unterminated string
+ "fail45.json", // nested beyond max depth
+ "fail3.json",
+ "fail4.json", // extra comma
+ "fail5.json", "fail6.json", "fail7.json", "fail8.json",
+ "fail9.json", // extra comma
+ "pass1.json", "pass2.json", "pass3.json", "pass4.json",
+ "round1.json", // round-trip test
+ "round2.json", // unicode
+ "round3.json", // bare string
+ "round4.json", // bare number
+ "round5.json", // bare true
+ "round6.json", // bare false
+ "round7.json", // bare null
};
// Test \u handling
-void unescape_unicode_test()
-{
+void unescape_unicode_test() {
UniValue val;
bool testResult;
// Escaped ASCII (quote)
testResult = val.read("[\"\\u0022\"]");
assert(testResult);
assert(val[0].get_str() == "\"");
// Escaped Basic Plane character, two-byte UTF-8
testResult = val.read("[\"\\u0191\"]");
assert(testResult);
assert(val[0].get_str() == "\xc6\x91");
// Escaped Basic Plane character, three-byte UTF-8
testResult = val.read("[\"\\u2191\"]");
assert(testResult);
assert(val[0].get_str() == "\xe2\x86\x91");
// Escaped Supplementary Plane character U+1d161
testResult = val.read("[\"\\ud834\\udd61\"]");
assert(testResult);
assert(val[0].get_str() == "\xf0\x9d\x85\xa1");
}
-void no_nul_test()
-{
+void no_nul_test() {
char buf[] = "___[1,2,3]___";
UniValue val;
assert(val.read({buf + 3, 7}));
}
-int main (int argc, char *argv[])
-{
- for (const auto& f: filenames) {
+int main(int argc, char *argv[]) {
+ for (const auto &f : filenames) {
runtest_file(f);
}
unescape_unicode_test();
no_nul_test();
return 0;
}
-

File Metadata

Mime Type
text/x-diff
Expires
Wed, May 21, 21:43 (1 d, 17 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5865994
Default Alt Text
(96 KB)

Event Timeline