diff --git a/.arclint b/.arclint --- a/.arclint +++ b/.arclint @@ -4,7 +4,7 @@ "type": "clang-format", "include": "(^src/.*\\.(h|c|cpp)$)", "exclude": [ - "(^src/(secp256k1|leveldb)/)", + "(^src/(secp256k1|univalue|leveldb)/)", "(^src/chainparamsseeds\\.h$)" ] }, diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -26,6 +26,8 @@ #include #include +using namespace RPCServer; + static bool fRPCRunning = false; static bool fRPCInWarmup = true; static std::string rpcWarmupStatus("RPC server started"); diff --git a/src/univalue/.travis.yml b/src/univalue/.travis.yml --- a/src/univalue/.travis.yml +++ b/src/univalue/.travis.yml @@ -25,6 +25,7 @@ - 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 diff --git a/src/univalue/Makefile.am b/src/univalue/Makefile.am --- a/src/univalue/Makefile.am +++ b/src/univalue/Makefile.am @@ -12,7 +12,6 @@ libunivalue_la_SOURCES = \ lib/univalue.cpp \ - lib/univalue_get.cpp \ lib/univalue_read.cpp \ lib/univalue_write.cpp @@ -21,7 +20,7 @@ -no-undefined libunivalue_la_CXXFLAGS = -I$(top_srcdir)/include -TESTS = test/object test/unitester test/no_nul +TESTS = test/unitester GENBIN = gen/gen$(BUILD_EXEEXT) GEN_SRCS = gen/gen.cpp @@ -34,7 +33,7 @@ @echo Updating $< $(AM_V_at)$(GENBIN) > lib/univalue_escapes.h -noinst_PROGRAMS = $(TESTS) test/test_json +noinst_PROGRAMS = $(TESTS) TEST_DATA_DIR=test @@ -43,21 +42,6 @@ test_unitester_CXXFLAGS = -I$(top_srcdir)/include -DJSON_TEST_SRC=\"$(srcdir)/$(TEST_DATA_DIR)\" test_unitester_LDFLAGS = -static $(LIBTOOL_APP_LDFLAGS) -test_test_json_SOURCES = test/test_json.cpp -test_test_json_LDADD = libunivalue.la -test_test_json_CXXFLAGS = -I$(top_srcdir)/include -test_test_json_LDFLAGS = -static $(LIBTOOL_APP_LDFLAGS) - -test_no_nul_SOURCES = test/no_nul.cpp -test_no_nul_LDADD = libunivalue.la -test_no_nul_CXXFLAGS = -I$(top_srcdir)/include -test_no_nul_LDFLAGS = -static $(LIBTOOL_APP_LDFLAGS) - -test_object_SOURCES = test/object.cpp -test_object_LDADD = libunivalue.la -test_object_CXXFLAGS = -I$(top_srcdir)/include -test_object_LDFLAGS = -static $(LIBTOOL_APP_LDFLAGS) - TEST_FILES = \ $(TEST_DATA_DIR)/fail10.json \ $(TEST_DATA_DIR)/fail11.json \ @@ -93,8 +77,6 @@ $(TEST_DATA_DIR)/fail39.json \ $(TEST_DATA_DIR)/fail40.json \ $(TEST_DATA_DIR)/fail41.json \ - $(TEST_DATA_DIR)/fail42.json \ - $(TEST_DATA_DIR)/fail44.json \ $(TEST_DATA_DIR)/fail3.json \ $(TEST_DATA_DIR)/fail4.json \ $(TEST_DATA_DIR)/fail5.json \ @@ -106,11 +88,6 @@ $(TEST_DATA_DIR)/pass2.json \ $(TEST_DATA_DIR)/pass3.json \ $(TEST_DATA_DIR)/round1.json \ - $(TEST_DATA_DIR)/round2.json \ - $(TEST_DATA_DIR)/round3.json \ - $(TEST_DATA_DIR)/round4.json \ - $(TEST_DATA_DIR)/round5.json \ - $(TEST_DATA_DIR)/round6.json \ - $(TEST_DATA_DIR)/round7.json + $(TEST_DATA_DIR)/round2.json EXTRA_DIST=$(TEST_FILES) $(GEN_SRCS) diff --git a/src/univalue/README b/src/univalue/README new file mode 100644 --- /dev/null +++ b/src/univalue/README @@ -0,0 +1,7 @@ + + UniValue + +A universal value object, with JSON encoding (output) and decoding (input). + +Built as a single dynamic RAII C++ object class, and no templates. + diff --git a/src/univalue/README.md b/src/univalue/README.md deleted file mode 100644 --- a/src/univalue/README.md +++ /dev/null @@ -1,32 +0,0 @@ - -# UniValue - -## Summary - -A universal value class, with JSON encoding and decoding. - -UniValue is an abstract data type that may be a null, boolean, string, -number, array container, or a key/value dictionary container, nested to -an arbitrary depth. - -This class is aligned with the JSON standard, [RFC -7159](https://tools.ietf.org/html/rfc7159.html). - -## 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 -``` - -## Design - -UniValue provides a single dynamic RAII C++ object class, -and minimizes template use (contra json_spirit). - diff --git a/src/univalue/configure.ac b/src/univalue/configure.ac --- a/src/univalue/configure.ac +++ b/src/univalue/configure.ac @@ -1,7 +1,7 @@ m4_define([libunivalue_major_version], [1]) m4_define([libunivalue_minor_version], [1]) -m4_define([libunivalue_micro_version], [3]) -m4_define([libunivalue_interface_age], [3]) +m4_define([libunivalue_micro_version], [2]) +m4_define([libunivalue_interface_age], [2]) # 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_version], [libunivalue_major_version().libunivalue_minor_version().libunivalue_micro_version()libunivalue_extraversion()]) -AC_INIT([univalue], [1.0.3], +AC_INIT([univalue], [1.0.2], [http://github.com/jgarzik/univalue/]) dnl make the compilation flags quiet unless V=1 is used diff --git a/src/univalue/gen/gen.cpp b/src/univalue/gen/gen.cpp --- a/src/univalue/gen/gen.cpp +++ b/src/univalue/gen/gen.cpp @@ -12,6 +12,8 @@ #include #include "univalue.h" +using namespace std; + static bool initEscapes; static std::string escapes[256]; diff --git a/src/univalue/include/univalue.h b/src/univalue/include/univalue.h --- a/src/univalue/include/univalue.h +++ b/src/univalue/include/univalue.h @@ -7,7 +7,6 @@ #define __UNIVALUE_H__ #include -#include #include #include @@ -70,11 +69,10 @@ size_t size() const { return values.size(); } bool getBool() const { return isTrue(); } - void getObjMap(std::map& kv) const; - bool checkObject(const std::map& memberTypes) const; + bool checkObject(const std::map& memberTypes); 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); } + const UniValue& operator[](unsigned int index) const; + bool exists(const std::string& key) const { return (findKey(key) >= 0); } bool isNull() const { return (typ == VNULL); } bool isTrue() const { return (typ == VBOOL) && (val == "1"); } @@ -94,25 +92,8 @@ 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(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& 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_); @@ -143,10 +124,9 @@ std::string write(unsigned int prettyIndent = 0, unsigned int indentLevel = 0) const; - bool read(const char *raw, size_t len); - bool read(const char *raw) { return read(raw, strlen(raw)); } + bool read(const char *raw); bool read(const std::string& rawStr) { - return read(rawStr.data(), rawStr.size()); + return read(rawStr.c_str()); } private: @@ -155,7 +135,7 @@ std::vector keys; std::vector values; - bool findKey(const std::string& key, size_t& retIdx) const; + int findKey(const std::string& key) const; void writeArray(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const; void writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const; @@ -260,7 +240,7 @@ }; extern enum jtokentype getJsonToken(std::string& tokenVal, - unsigned int& consumed, const char *raw, const char *end); + unsigned int& consumed, const char *raw); extern const char *uvTypeName(UniValue::VType t); static inline bool jsonTokenIsValue(enum jtokentype jtt) diff --git a/src/univalue/lib/univalue.cpp b/src/univalue/lib/univalue.cpp --- a/src/univalue/lib/univalue.cpp +++ b/src/univalue/lib/univalue.cpp @@ -4,12 +4,77 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include +#include #include +#include #include +#include #include +#include #include "univalue.h" +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 + return false; + if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed + return false; + return true; +} + +bool ParseInt32(const std::string& str, int32_t *out) +{ + if (!ParsePrechecks(str)) + return false; + char *endp = NULL; + 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 + // 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::min() && + n <= std::numeric_limits::max(); +} + +bool ParseInt64(const std::string& str, int64_t *out) +{ + if (!ParsePrechecks(str)) + return false; + char *endp = NULL; + 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::min() && + n <= std::numeric_limits::max(); +} + +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; + return text.eof() && !text.fail(); +} +} + +using namespace std; + const UniValue NullUniValue; void UniValue::clear() @@ -35,15 +100,15 @@ return true; } -static bool validNumStr(const std::string& s) +static bool validNumStr(const string& s) { - std::string tokenVal; + string tokenVal; unsigned int consumed; - enum jtokentype tt = getJsonToken(tokenVal, consumed, s.data(), s.data() + s.size()); + enum jtokentype tt = getJsonToken(tokenVal, consumed, s.c_str()); return (tt == JTOK_NUMBER); } -bool UniValue::setNumStr(const std::string& val_) +bool UniValue::setNumStr(const string& val_) { if (!validNumStr(val_)) return false; @@ -56,7 +121,7 @@ bool UniValue::setInt(uint64_t val_) { - std::ostringstream oss; + ostringstream oss; oss << val_; @@ -65,7 +130,7 @@ bool UniValue::setInt(int64_t val_) { - std::ostringstream oss; + ostringstream oss; oss << val_; @@ -74,7 +139,7 @@ bool UniValue::setFloat(double val_) { - std::ostringstream oss; + ostringstream oss; oss << std::setprecision(16) << val_; @@ -83,7 +148,7 @@ return ret; } -bool UniValue::setStr(const std::string& val_) +bool UniValue::setStr(const string& val_) { clear(); typ = VSTR; @@ -124,22 +189,13 @@ return true; } -void UniValue::__pushKV(const std::string& key, const UniValue& val_) -{ - keys.push_back(key); - values.push_back(val_); -} - bool UniValue::pushKV(const std::string& key, const UniValue& val_) { if (typ != VOBJ) return false; - size_t idx; - if (findKey(key, idx)) - values[idx] = val_; - else - __pushKV(key, val_); + keys.push_back(key); + values.push_back(val_); return true; } @@ -148,43 +204,30 @@ if (typ != VOBJ || obj.typ != VOBJ) return false; - for (size_t i = 0; i < obj.keys.size(); i++) - __pushKV(obj.keys[i], obj.values.at(i)); + for (unsigned int i = 0; i < obj.keys.size(); i++) { + keys.push_back(obj.keys[i]); + values.push_back(obj.values.at(i)); + } return true; } -void UniValue::getObjMap(std::map& 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 +int UniValue::findKey(const std::string& key) const { - for (size_t i = 0; i < keys.size(); i++) { - if (keys[i] == key) { - retIdx = i; - return true; - } + for (unsigned int i = 0; i < keys.size(); i++) { + if (keys[i] == key) + return (int) i; } - return false; + return -1; } -bool UniValue::checkObject(const std::map& t) const +bool UniValue::checkObject(const std::map& t) { - if (typ != VOBJ) - return false; - for (std::map::const_iterator it = t.begin(); it != t.end(); ++it) { - size_t idx = 0; - if (!findKey(it->first, idx)) + int idx = findKey(it->first); + if (idx < 0) return false; if (values.at(idx).getType() != it->second) @@ -199,14 +242,14 @@ if (typ != VOBJ) return NullUniValue; - size_t index = 0; - if (!findKey(key, index)) + int index = findKey(key); + if (index < 0) return NullUniValue; return values.at(index); } -const UniValue& UniValue::operator[](size_t index) const +const UniValue& UniValue::operator[](unsigned int index) const { if (typ != VOBJ && typ != VARR) return NullUniValue; @@ -240,3 +283,75 @@ return NullUniValue; } +const std::vector& UniValue::getKeys() const +{ + if (typ != VOBJ) + throw std::runtime_error("JSON value is not an object as expected"); + return keys; +} + +const std::vector& UniValue::getValues() const +{ + if (typ != VOBJ && typ != VARR) + throw std::runtime_error("JSON value is not an object or array as expected"); + return values; +} + +bool UniValue::get_bool() const +{ + if (typ != VBOOL) + throw std::runtime_error("JSON value is not a boolean as expected"); + return getBool(); +} + +const std::string& UniValue::get_str() const +{ + if (typ != VSTR) + throw std::runtime_error("JSON value is not a string as expected"); + 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) + throw std::runtime_error("JSON value is not a number as expected"); + double retval; + if (!ParseDouble(getValStr(), &retval)) + throw std::runtime_error("JSON double out of range"); + return retval; +} + +const UniValue& UniValue::get_obj() const +{ + if (typ != VOBJ) + throw std::runtime_error("JSON value is not an object as expected"); + return *this; +} + +const UniValue& UniValue::get_array() const +{ + if (typ != VARR) + throw std::runtime_error("JSON value is not an array as expected"); + return *this; +} + diff --git a/src/univalue/lib/univalue_get.cpp b/src/univalue/lib/univalue_get.cpp deleted file mode 100644 --- a/src/univalue/lib/univalue_get.cpp +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright 2014 BitPay Inc. -// Copyright 2015 Bitcoin Core Developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "univalue.h" - -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 - return false; - if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed - return false; - return true; -} - -bool ParseInt32(const std::string& str, int32_t *out) -{ - if (!ParsePrechecks(str)) - return false; - char *endp = NULL; - 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 - // 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::min() && - n <= std::numeric_limits::max(); -} - -bool ParseInt64(const std::string& str, int64_t *out) -{ - if (!ParsePrechecks(str)) - return false; - char *endp = NULL; - 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::min() && - n <= std::numeric_limits::max(); -} - -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; - return text.eof() && !text.fail(); -} -} - -const std::vector& UniValue::getKeys() const -{ - if (typ != VOBJ) - throw std::runtime_error("JSON value is not an object as expected"); - return keys; -} - -const std::vector& UniValue::getValues() const -{ - if (typ != VOBJ && typ != VARR) - throw std::runtime_error("JSON value is not an object or array as expected"); - return values; -} - -bool UniValue::get_bool() const -{ - if (typ != VBOOL) - throw std::runtime_error("JSON value is not a boolean as expected"); - return getBool(); -} - -const std::string& UniValue::get_str() const -{ - if (typ != VSTR) - throw std::runtime_error("JSON value is not a string as expected"); - 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) - throw std::runtime_error("JSON value is not a number as expected"); - double retval; - if (!ParseDouble(getValStr(), &retval)) - throw std::runtime_error("JSON double out of range"); - return retval; -} - -const UniValue& UniValue::get_obj() const -{ - if (typ != VOBJ) - throw std::runtime_error("JSON value is not an object as expected"); - return *this; -} - -const UniValue& UniValue::get_array() const -{ - if (typ != VARR) - throw std::runtime_error("JSON value is not an array as expected"); - return *this; -} - diff --git a/src/univalue/lib/univalue_read.cpp b/src/univalue/lib/univalue_read.cpp --- a/src/univalue/lib/univalue_read.cpp +++ b/src/univalue/lib/univalue_read.cpp @@ -8,6 +8,8 @@ #include "univalue.h" #include "univalue_utffilter.h" +using namespace std; + static bool json_isdigit(int ch) { return ((ch >= '0') && (ch <= '9')); @@ -40,22 +42,22 @@ return first; } -enum jtokentype getJsonToken(std::string& tokenVal, unsigned int& consumed, - const char *raw, const char *end) +enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed, + const char *raw) { tokenVal.clear(); consumed = 0; const char *rawStart = raw; - while (raw < end && (json_isspace(*raw))) // skip whitespace + while ((*raw) && (json_isspace(*raw))) // skip whitespace raw++; - if (raw >= end) - return JTOK_NONE; - switch (*raw) { + case 0: + return JTOK_NONE; + case '{': raw++; consumed = (raw - rawStart); @@ -112,7 +114,7 @@ case '8': case '9': { // part 1: int - std::string numStr; + string numStr; const char *first = raw; @@ -125,40 +127,40 @@ numStr += *raw; // copy first char raw++; - if ((*first == '-') && (raw < end) && (!json_isdigit(*raw))) + if ((*first == '-') && (!json_isdigit(*raw))) return JTOK_ERR; - while (raw < end && json_isdigit(*raw)) { // copy digits + while ((*raw) && json_isdigit(*raw)) { // copy digits numStr += *raw; raw++; } // part 2: frac - if (raw < end && *raw == '.') { + if (*raw == '.') { numStr += *raw; // copy . raw++; - if (raw >= end || !json_isdigit(*raw)) + if (!json_isdigit(*raw)) return JTOK_ERR; - while (raw < end && json_isdigit(*raw)) { // copy digits + while ((*raw) && json_isdigit(*raw)) { // copy digits numStr += *raw; raw++; } } // part 3: exp - if (raw < end && (*raw == 'e' || *raw == 'E')) { + if (*raw == 'e' || *raw == 'E') { numStr += *raw; // copy E raw++; - if (raw < end && (*raw == '-' || *raw == '+')) { // copy +/- + if (*raw == '-' || *raw == '+') { // copy +/- numStr += *raw; raw++; } - if (raw >= end || !json_isdigit(*raw)) + if (!json_isdigit(*raw)) return JTOK_ERR; - while (raw < end && json_isdigit(*raw)) { // copy digits + while ((*raw) && json_isdigit(*raw)) { // copy digits numStr += *raw; raw++; } @@ -172,19 +174,16 @@ case '"': { raw++; // skip " - std::string valStr; + string valStr; JSONUTF8StringFilter writer(valStr); - while (true) { - if (raw >= end || (unsigned char)*raw < 0x20) + while (*raw) { + if ((unsigned char)*raw < 0x20) return JTOK_ERR; else if (*raw == '\\') { raw++; // skip backslash - if (raw >= end) - return JTOK_ERR; - switch (*raw) { case '"': writer.push_back('\"'); break; case '\\': writer.push_back('\\'); break; @@ -197,8 +196,7 @@ case 'u': { unsigned int codepoint; - if (raw + 1 + 4 >= end || - hatoui(raw + 1, raw + 1 + 4, codepoint) != + if (hatoui(raw + 1, raw + 1 + 4, codepoint) != raw + 1 + 4) return JTOK_ERR; writer.push_back_u(codepoint); @@ -248,22 +246,21 @@ #define setExpect(bit) (expectMask |= EXP_##bit) #define clearExpect(bit) (expectMask &= ~EXP_##bit) -bool UniValue::read(const char *raw, size_t size) +bool UniValue::read(const char *raw) { clear(); uint32_t expectMask = 0; - std::vector stack; + vector stack; - std::string tokenVal; + string tokenVal; unsigned int consumed; enum jtokentype tok = JTOK_NONE; enum jtokentype last_tok = JTOK_NONE; - const char* end = raw + size; do { last_tok = tok; - tok = getJsonToken(tokenVal, consumed, raw, end); + tok = getJsonToken(tokenVal, consumed, raw); if (tok == JTOK_NONE || tok == JTOK_ERR) return false; raw += consumed; @@ -374,6 +371,9 @@ case JTOK_KW_NULL: case JTOK_KW_TRUE: case JTOK_KW_FALSE: { + if (!stack.size()) + return false; + UniValue tmpVal; switch (tok) { case JTOK_KW_NULL: @@ -388,11 +388,6 @@ default: /* impossible */ break; } - if (!stack.size()) { - *this = tmpVal; - break; - } - UniValue *top = stack.back(); top->values.push_back(tmpVal); @@ -401,12 +396,10 @@ } case JTOK_NUMBER: { - UniValue tmpVal(VNUM, tokenVal); - if (!stack.size()) { - *this = tmpVal; - break; - } + if (!stack.size()) + return false; + UniValue tmpVal(VNUM, tokenVal); UniValue *top = stack.back(); top->values.push_back(tmpVal); @@ -415,18 +408,17 @@ } case JTOK_STRING: { + if (!stack.size()) + return false; + + UniValue *top = stack.back(); + 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); } @@ -440,7 +432,7 @@ } while (!stack.empty ()); /* Check that nothing follows the initial construct (parsed above). */ - tok = getJsonToken(tokenVal, consumed, raw, end); + tok = getJsonToken(tokenVal, consumed, raw); if (tok != JTOK_NONE) return false; diff --git a/src/univalue/lib/univalue_utffilter.h b/src/univalue/lib/univalue_utffilter.h --- a/src/univalue/lib/univalue_utffilter.h +++ b/src/univalue/lib/univalue_utffilter.h @@ -13,7 +13,7 @@ class JSONUTF8StringFilter { public: - explicit JSONUTF8StringFilter(std::string &s): + JSONUTF8StringFilter(std::string &s): str(s), is_valid(true), codepoint(0), state(0), surpair(0) { } @@ -46,19 +46,19 @@ } } // 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 + surpair = codepoint; + } 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; @@ -66,7 +66,7 @@ if (surpair) // First half of surrogate pair not followed by second - fail is_valid = false; else - append_codepoint(codepoint_); + append_codepoint(codepoint); } } // Check that we're in a state where the string can be ended @@ -96,22 +96,22 @@ // 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))); + 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))); } } }; diff --git a/src/univalue/lib/univalue_write.cpp b/src/univalue/lib/univalue_write.cpp --- a/src/univalue/lib/univalue_write.cpp +++ b/src/univalue/lib/univalue_write.cpp @@ -8,9 +8,11 @@ #include "univalue.h" #include "univalue_escapes.h" -static std::string json_escape(const std::string& inS) +using namespace std; + +static string json_escape(const string& inS) { - std::string outS; + string outS; outS.reserve(inS.size() * 2); for (unsigned int i = 0; i < inS.size(); i++) { @@ -26,10 +28,10 @@ return outS; } -std::string UniValue::write(unsigned int prettyIndent, - unsigned int indentLevel) const +string UniValue::write(unsigned int prettyIndent, + unsigned int indentLevel) const { - std::string s; + string s; s.reserve(1024); unsigned int modIndent = indentLevel; @@ -60,12 +62,12 @@ return s; } -static void indentStr(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) +static void indentStr(unsigned int prettyIndent, unsigned int indentLevel, string& s) { s.append(prettyIndent * indentLevel, ' '); } -void UniValue::writeArray(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const +void UniValue::writeArray(unsigned int prettyIndent, unsigned int indentLevel, string& s) const { s += "["; if (prettyIndent) @@ -77,6 +79,8 @@ s += values[i].write(prettyIndent, indentLevel + 1); if (i != (values.size() - 1)) { s += ","; + if (prettyIndent) + s += " "; } if (prettyIndent) s += "\n"; @@ -87,7 +91,7 @@ s += "]"; } -void UniValue::writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const +void UniValue::writeObject(unsigned int prettyIndent, unsigned int indentLevel, string& s) const { s += "{"; if (prettyIndent) diff --git a/src/univalue/test/.gitignore b/src/univalue/test/.gitignore --- a/src/univalue/test/.gitignore +++ b/src/univalue/test/.gitignore @@ -1,8 +1,4 @@ - -object unitester -test_json -no_nul *.trs *.log diff --git a/src/univalue/test/fail1.json b/src/univalue/test/fail1.json --- a/src/univalue/test/fail1.json +++ b/src/univalue/test/fail1.json @@ -1 +1 @@ -"This is a string that never ends, yes it goes on and on, my friends. +"A JSON payload should be an object or array, not a string." \ No newline at end of file diff --git a/src/univalue/test/fail42.json b/src/univalue/test/fail42.json deleted file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@ -#include -#include -#include -#include -#include -#include - -#define BOOST_FIXTURE_TEST_SUITE(a, b) -#define BOOST_AUTO_TEST_CASE(funcName) void funcName() -#define BOOST_AUTO_TEST_SUITE_END() -#define BOOST_CHECK(expr) assert(expr) -#define BOOST_CHECK_EQUAL(v1, v2) assert((v1) == (v2)) -#define BOOST_CHECK_THROW(stmt, excMatch) { \ - try { \ - (stmt); \ - } catch (excMatch & e) { \ - } catch (...) { \ - assert(0); \ - } \ - } -#define BOOST_CHECK_NO_THROW(stmt) { \ - try { \ - (stmt); \ - } catch (...) { \ - assert(0); \ - } \ - } - -BOOST_FIXTURE_TEST_SUITE(univalue_tests, BasicTestingSetup) - -BOOST_AUTO_TEST_CASE(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; - BOOST_CHECK(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"); -} - -BOOST_AUTO_TEST_CASE(univalue_typecheck) -{ - UniValue v1; - BOOST_CHECK(v1.setNumStr("1")); - BOOST_CHECK(v1.isNum()); - BOOST_CHECK_THROW(v1.get_bool(), std::runtime_error); - - UniValue v2; - BOOST_CHECK(v2.setBool(true)); - BOOST_CHECK_EQUAL(v2.get_bool(), true); - BOOST_CHECK_THROW(v2.get_int(), std::runtime_error); - - UniValue v3; - BOOST_CHECK(v3.setNumStr("32482348723847471234")); - BOOST_CHECK_THROW(v3.get_int64(), std::runtime_error); - BOOST_CHECK(v3.setNumStr("1000")); - BOOST_CHECK_EQUAL(v3.get_int64(), 1000); - - UniValue v4; - BOOST_CHECK(v4.setNumStr("2147483648")); - BOOST_CHECK_EQUAL(v4.get_int64(), 2147483648); - BOOST_CHECK_THROW(v4.get_int(), std::runtime_error); - BOOST_CHECK(v4.setNumStr("1000")); - BOOST_CHECK_EQUAL(v4.get_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 vals = v5.getValues(); - BOOST_CHECK_THROW(vals[0].get_int(), std::runtime_error); - BOOST_CHECK_EQUAL(vals[0].get_bool(), true); - - BOOST_CHECK_EQUAL(vals[1].get_int(), 10); - BOOST_CHECK_THROW(vals[1].get_bool(), std::runtime_error); -} - -BOOST_AUTO_TEST_CASE(univalue_set) -{ - UniValue v(UniValue::VSTR, "foo"); - v.clear(); - BOOST_CHECK(v.isNull()); - BOOST_CHECK_EQUAL(v.getValStr(), ""); - - BOOST_CHECK(v.setObject()); - BOOST_CHECK(v.isObject()); - BOOST_CHECK_EQUAL(v.size(), 0); - BOOST_CHECK_EQUAL(v.getType(), UniValue::VOBJ); - BOOST_CHECK(v.empty()); - - BOOST_CHECK(v.setArray()); - BOOST_CHECK(v.isArray()); - BOOST_CHECK_EQUAL(v.size(), 0); - - BOOST_CHECK(v.setStr("zum")); - BOOST_CHECK(v.isStr()); - BOOST_CHECK_EQUAL(v.getValStr(), "zum"); - - BOOST_CHECK(v.setFloat(-1.01)); - BOOST_CHECK(v.isNum()); - BOOST_CHECK_EQUAL(v.getValStr(), "-1.01"); - - BOOST_CHECK(v.setInt((int)1023)); - BOOST_CHECK(v.isNum()); - BOOST_CHECK_EQUAL(v.getValStr(), "1023"); - - BOOST_CHECK(v.setInt((int64_t)-1023LL)); - BOOST_CHECK(v.isNum()); - BOOST_CHECK_EQUAL(v.getValStr(), "-1023"); - - BOOST_CHECK(v.setInt((uint64_t)1023ULL)); - BOOST_CHECK(v.isNum()); - BOOST_CHECK_EQUAL(v.getValStr(), "1023"); - - BOOST_CHECK(v.setNumStr("-688")); - BOOST_CHECK(v.isNum()); - BOOST_CHECK_EQUAL(v.getValStr(), "-688"); - - BOOST_CHECK(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.getBool(), false); - - BOOST_CHECK(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.getBool(), true); - - BOOST_CHECK(!v.setNumStr("zombocom")); - - BOOST_CHECK(v.setNull()); - BOOST_CHECK(v.isNull()); -} - -BOOST_AUTO_TEST_CASE(univalue_array) -{ - UniValue arr(UniValue::VARR); - - UniValue v((int64_t)1023LL); - BOOST_CHECK(arr.push_back(v)); - - std::string vStr("zippy"); - BOOST_CHECK(arr.push_back(vStr)); - - const char *s = "pippy"; - BOOST_CHECK(arr.push_back(s)); - - std::vector vec; - v.setStr("boing"); - vec.push_back(v); - - v.setStr("going"); - vec.push_back(v); - - BOOST_CHECK(arr.push_backV(vec)); - - BOOST_CHECK(arr.push_back((uint64_t) 400ULL)); - BOOST_CHECK(arr.push_back((int64_t) -400LL)); - BOOST_CHECK(arr.push_back((int) -401)); - BOOST_CHECK(arr.push_back(-40.1)); - - BOOST_CHECK_EQUAL(arr.empty(), false); - BOOST_CHECK_EQUAL(arr.size(), 9); - - BOOST_CHECK_EQUAL(arr[0].getValStr(), "1023"); - BOOST_CHECK_EQUAL(arr[1].getValStr(), "zippy"); - BOOST_CHECK_EQUAL(arr[2].getValStr(), "pippy"); - BOOST_CHECK_EQUAL(arr[3].getValStr(), "boing"); - BOOST_CHECK_EQUAL(arr[4].getValStr(), "going"); - BOOST_CHECK_EQUAL(arr[5].getValStr(), "400"); - BOOST_CHECK_EQUAL(arr[6].getValStr(), "-400"); - BOOST_CHECK_EQUAL(arr[7].getValStr(), "-401"); - BOOST_CHECK_EQUAL(arr[8].getValStr(), "-40.1"); - - BOOST_CHECK_EQUAL(arr[999].getValStr(), ""); - - arr.clear(); - BOOST_CHECK(arr.empty()); - BOOST_CHECK_EQUAL(arr.size(), 0); -} - -BOOST_AUTO_TEST_CASE(univalue_object) -{ - UniValue obj(UniValue::VOBJ); - std::string strKey, strVal; - UniValue v; - - strKey = "age"; - v.setInt(100); - BOOST_CHECK(obj.pushKV(strKey, v)); - - strKey = "first"; - strVal = "John"; - BOOST_CHECK(obj.pushKV(strKey, strVal)); - - strKey = "last"; - const char *cVal = "Smith"; - BOOST_CHECK(obj.pushKV(strKey, cVal)); - - strKey = "distance"; - BOOST_CHECK(obj.pushKV(strKey, (int64_t) 25)); - - strKey = "time"; - BOOST_CHECK(obj.pushKV(strKey, (uint64_t) 3600)); - - strKey = "calories"; - BOOST_CHECK(obj.pushKV(strKey, (int) 12)); - - strKey = "temperature"; - BOOST_CHECK(obj.pushKV(strKey, (double) 90.012)); - - UniValue obj2(UniValue::VOBJ); - BOOST_CHECK(obj2.pushKV("cat1", 9000)); - BOOST_CHECK(obj2.pushKV("cat2", 12345)); - - BOOST_CHECK(obj.pushKVs(obj2)); - - BOOST_CHECK_EQUAL(obj.empty(), false); - BOOST_CHECK_EQUAL(obj.size(), 9); - - 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["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("cat1")); - BOOST_CHECK(obj.exists("cat2")); - - BOOST_CHECK(!obj.exists("nyuknyuknyuk")); - - std::map 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["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); - - BOOST_CHECK_EQUAL(obj.setObject(), true); - UniValue uv; - uv.setInt(42); - obj.__pushKV("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 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\"}}]"; - -BOOST_AUTO_TEST_CASE(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()); - - /* 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")); -} - -BOOST_AUTO_TEST_SUITE_END() - -int main (int argc, char *argv[]) -{ - univalue_constructor(); - univalue_typecheck(); - univalue_set(); - univalue_array(); - univalue_object(); - univalue_readwrite(); - return 0; -} - diff --git a/src/univalue/test/round3.json b/src/univalue/test/round3.json deleted file mode 100644 --- a/src/univalue/test/round3.json +++ /dev/null @@ -1 +0,0 @@ -"abcdefghijklmnopqrstuvwxyz" diff --git a/src/univalue/test/round4.json b/src/univalue/test/round4.json deleted file mode 100644 --- a/src/univalue/test/round4.json +++ /dev/null @@ -1 +0,0 @@ -7 diff --git a/src/univalue/test/round5.json b/src/univalue/test/round5.json deleted file mode 100644 --- a/src/univalue/test/round5.json +++ /dev/null @@ -1 +0,0 @@ -true diff --git a/src/univalue/test/round6.json b/src/univalue/test/round6.json deleted file mode 100644 --- a/src/univalue/test/round6.json +++ /dev/null @@ -1 +0,0 @@ -false diff --git a/src/univalue/test/round7.json b/src/univalue/test/round7.json deleted file mode 100644 --- a/src/univalue/test/round7.json +++ /dev/null @@ -1 +0,0 @@ -null diff --git a/src/univalue/test/test_json.cpp b/src/univalue/test/test_json.cpp deleted file mode 100644 --- a/src/univalue/test/test_json.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// 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 -#include -#include "univalue.h" - -using namespace std; - -int main (int argc, char *argv[]) -{ - UniValue val; - if (val.read(string(istreambuf_iterator(cin), - istreambuf_iterator()))) { - 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 --- a/src/univalue/test/unitester.cpp +++ b/src/univalue/test/unitester.cpp @@ -17,7 +17,8 @@ #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) #endif -std::string srcdir(JSON_TEST_SRC); +using namespace std; +string srcdir(JSON_TEST_SRC); static bool test_failed = false; #define d_assert(expr) { if (!(expr)) { test_failed = true; fprintf(stderr, "%s failed\n", filename.c_str()); } } @@ -29,9 +30,9 @@ return s; } -static void runtest(std::string filename, const std::string& jdata) +static void runtest(string filename, const string& jdata) { - std::string prefix = filename.substr(0, 4); + string prefix = filename.substr(0, 4); bool wantPass = (prefix == "pass") || (prefix == "roun"); bool wantFail = (prefix == "fail"); @@ -55,19 +56,19 @@ static void runtest_file(const char *filename_) { - std::string basename(filename_); - std::string filename = srcdir + "/" + basename; + string basename(filename_); + string filename = srcdir + "/" + basename; FILE *f = fopen(filename.c_str(), "r"); assert(f != NULL); - std::string jdata; + string jdata; char buf[4096]; while (!feof(f)) { int bread = fread(buf, 1, sizeof(buf), f); assert(!ferror(f)); - std::string s(buf, bread); + string s(buf, bread); jdata += s; } @@ -112,8 +113,6 @@ "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 "fail3.json", "fail4.json", // extra comma "fail5.json", @@ -126,11 +125,6 @@ "pass3.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