diff options
Diffstat (limited to 'src/univalue')
57 files changed, 597 insertions, 11 deletions
diff --git a/src/univalue/.gitignore b/src/univalue/.gitignore new file mode 100644 index 0000000000..a7a2ca9197 --- /dev/null +++ b/src/univalue/.gitignore @@ -0,0 +1,31 @@ +.deps/ +INSTALL +Makefile +Makefile.in +aclocal.m4 +autom4te.cache/ +compile +config.log +config.status +config.guess +config.sub +configure +depcomp +install-sh +missing +stamp-h1 +univalue-config.h* +test-driver +libtool +ltmain.sh + +*.a +*.la +*.lo +*.logs +*.o +*.pc +*.trs + +.dirstamp +.libs diff --git a/src/univalue/.travis.yml b/src/univalue/.travis.yml new file mode 100644 index 0000000000..af632c78d9 --- /dev/null +++ b/src/univalue/.travis.yml @@ -0,0 +1,52 @@ + +language: cpp + +compiler: + - clang + - gcc + +os: + - linux + - osx + +sudo: false + +env: + global: + - MAKEJOBS=-j3 + - RUN_TESTS=true + - BASE_OUTDIR=$TRAVIS_BUILD_DIR/out + +cache: + apt: true + +addons: + apt: + packages: + - pkg-config + +before_script: + - if [ -n "$USE_SHELL" ]; then export CONFIG_SHELL="$USE_SHELL"; fi + - test -n "$USE_SHELL" && eval '"$USE_SHELL" -c "./autogen.sh"' || ./autogen.sh + +script: + - if [ -n "$UNIVALUE_CONFIG" ]; then unset CC; unset CXX; fi + - OUTDIR=$BASE_OUTDIR/$TRAVIS_PULL_REQUEST/$TRAVIS_JOB_NUMBER-$HOST + - UNIVALUE_CONFIG_ALL="--prefix=$TRAVIS_BUILD_DIR/depends/$HOST --bindir=$OUTDIR/bin --libdir=$OUTDIR/lib" + - ./configure --cache-file=config.cache $UNIVALUE_CONFIG_ALL $UNIVALUE_CONFIG || ( cat config.log && false) + - make -s $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && make $GOAL ; false ) + - export LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/depends/$HOST/lib + - if [ "$RUN_TESTS" = "true" ]; then make check; fi + +matrix: + fast_finish: true + include: + - os: linux + compiler: gcc + env: UNIVALUE_CONFIG=--host=x86_64-w64-mingw32 RUN_TESTS=false + addons: + apt: + packages: + - g++-mingw-w64-x86-64 + - gcc-mingw-w64-x86-64 + - binutils-mingw-w64-x86-64 diff --git a/src/univalue/COPYING b/src/univalue/COPYING new file mode 100644 index 0000000000..1fb429f356 --- /dev/null +++ b/src/univalue/COPYING @@ -0,0 +1,19 @@ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/src/univalue/Makefile.am b/src/univalue/Makefile.am new file mode 100644 index 0000000000..df9e66229c --- /dev/null +++ b/src/univalue/Makefile.am @@ -0,0 +1,84 @@ +ACLOCAL_AMFLAGS = -I build-aux/m4 +.PHONY: gen +.INTERMEDIATE: $(GENBIN) + +include_HEADERS = include/univalue.h +noinst_HEADERS = lib/univalue_escapes.h + +lib_LTLIBRARIES = libunivalue.la + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = pc/libunivalue.pc + +libunivalue_la_SOURCES = \ + lib/univalue.cpp \ + lib/univalue_read.cpp \ + lib/univalue_write.cpp + +libunivalue_la_LDFLAGS = \ + -version-info $(LIBUNIVALUE_CURRENT):$(LIBUNIVALUE_REVISION):$(LIBUNIVALUE_AGE) \ + -no-undefined +libunivalue_la_CXXFLAGS = -I$(top_srcdir)/include + +TESTS = test/unitester + +GENBIN = gen/gen$(BUILD_EXEEXT) +GEN_SRCS = gen/gen.cpp + +$(GENBIN): $(GEN_SRCS) + @echo Building $@ + $(AM_V_at)c++ -I$(top_srcdir)/include -o $@ $< + +gen: lib/univalue_escapes.h $(GENBIN) + @echo Updating $< + $(AM_V_at)$(GENBIN) > lib/univalue_escapes.h + +noinst_PROGRAMS = $(TESTS) + +TEST_DATA_DIR=test + +test_unitester_SOURCES = test/unitester.cpp +test_unitester_LDADD = libunivalue.la +test_unitester_CXXFLAGS = -I$(top_srcdir)/include -DJSON_TEST_SRC=\"$(srcdir)/$(TEST_DATA_DIR)\" +test_unitester_LDFLAGS = -static $(LIBTOOL_APP_LDFLAGS) + +TEST_FILES = \ + $(TEST_DATA_DIR)/fail10.json \ + $(TEST_DATA_DIR)/fail11.json \ + $(TEST_DATA_DIR)/fail12.json \ + $(TEST_DATA_DIR)/fail13.json \ + $(TEST_DATA_DIR)/fail14.json \ + $(TEST_DATA_DIR)/fail15.json \ + $(TEST_DATA_DIR)/fail16.json \ + $(TEST_DATA_DIR)/fail17.json \ + $(TEST_DATA_DIR)/fail18.json \ + $(TEST_DATA_DIR)/fail19.json \ + $(TEST_DATA_DIR)/fail1.json \ + $(TEST_DATA_DIR)/fail20.json \ + $(TEST_DATA_DIR)/fail21.json \ + $(TEST_DATA_DIR)/fail22.json \ + $(TEST_DATA_DIR)/fail23.json \ + $(TEST_DATA_DIR)/fail24.json \ + $(TEST_DATA_DIR)/fail25.json \ + $(TEST_DATA_DIR)/fail26.json \ + $(TEST_DATA_DIR)/fail27.json \ + $(TEST_DATA_DIR)/fail28.json \ + $(TEST_DATA_DIR)/fail29.json \ + $(TEST_DATA_DIR)/fail2.json \ + $(TEST_DATA_DIR)/fail30.json \ + $(TEST_DATA_DIR)/fail31.json \ + $(TEST_DATA_DIR)/fail32.json \ + $(TEST_DATA_DIR)/fail33.json \ + $(TEST_DATA_DIR)/fail34.json \ + $(TEST_DATA_DIR)/fail3.json \ + $(TEST_DATA_DIR)/fail4.json \ + $(TEST_DATA_DIR)/fail5.json \ + $(TEST_DATA_DIR)/fail6.json \ + $(TEST_DATA_DIR)/fail7.json \ + $(TEST_DATA_DIR)/fail8.json \ + $(TEST_DATA_DIR)/fail9.json \ + $(TEST_DATA_DIR)/pass1.json \ + $(TEST_DATA_DIR)/pass2.json \ + $(TEST_DATA_DIR)/pass3.json + +EXTRA_DIST=$(TEST_FILES) $(GEN_SRCS) diff --git a/src/univalue/README b/src/univalue/README new file mode 100644 index 0000000000..48167b083b --- /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/TODO b/src/univalue/TODO new file mode 100644 index 0000000000..5530048e92 --- /dev/null +++ b/src/univalue/TODO @@ -0,0 +1,10 @@ + +Rearrange tree for easier 'git subtree' style use + +Move towards C++11 etc. + +Namespace support - must come up with useful shorthand, avoiding +long Univalue::Univalue::Univalue usages forced upon library users. + +Improve test suite + diff --git a/src/univalue/autogen.sh b/src/univalue/autogen.sh new file mode 100755 index 0000000000..4b38721faa --- /dev/null +++ b/src/univalue/autogen.sh @@ -0,0 +1,9 @@ +#!/bin/sh +set -e +srcdir="$(dirname $0)" +cd "$srcdir" +if [ -z ${LIBTOOLIZE} ] && GLIBTOOLIZE="`which glibtoolize 2>/dev/null`"; then + LIBTOOLIZE="${GLIBTOOLIZE}" + export LIBTOOLIZE +fi +autoreconf --install --force diff --git a/src/univalue/build-aux/m4/.gitignore b/src/univalue/build-aux/m4/.gitignore new file mode 100644 index 0000000000..f063686524 --- /dev/null +++ b/src/univalue/build-aux/m4/.gitignore @@ -0,0 +1 @@ +/*.m4 diff --git a/src/univalue/configure.ac b/src/univalue/configure.ac new file mode 100644 index 0000000000..6cd9516229 --- /dev/null +++ b/src/univalue/configure.ac @@ -0,0 +1,69 @@ +m4_define([libunivalue_major_version], [1]) +m4_define([libunivalue_minor_version], [1]) +m4_define([libunivalue_micro_version], [1]) +m4_define([libunivalue_interface_age], [1]) +# If you need a modifier for the version number. +# Normally empty, but can be used to make "fixup" releases. +m4_define([libunivalue_extraversion], []) + +dnl libtool versioning from libunivalue +m4_define([libunivalue_current], [m4_eval(100 * libunivalue_minor_version + libunivalue_micro_version - libunivalue_interface_age)]) +m4_define([libunivalue_binary_age], [m4_eval(100 * libunivalue_minor_version + libunivalue_micro_version)]) +m4_define([libunivalue_revision], [libunivalue_interface_age]) +m4_define([libunivalue_age], [m4_eval(libunivalue_binary_age - libunivalue_interface_age)]) +m4_define([libunivalue_version], [libunivalue_major_version().libunivalue_minor_version().libunivalue_micro_version()libunivalue_extraversion()]) + + +AC_INIT([univalue], [1.0.0], + [http://github.com/jgarzik/univalue/]) + +dnl make the compilation flags quiet unless V=1 is used +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +AC_PREREQ(2.60) +AC_CONFIG_SRCDIR([lib/univalue.cpp]) +AC_CONFIG_AUX_DIR([build-aux]) +AC_CONFIG_MACRO_DIR([build-aux/m4]) +AC_CONFIG_HEADERS([univalue-config.h]) +AM_INIT_AUTOMAKE([subdir-objects foreign]) + +LIBUNIVALUE_MAJOR_VERSION=libunivalue_major_version +LIBUNIVALUE_MINOR_VERSION=libunivalue_minor_version +LIBUNIVALUE_MICRO_VERSION=libunivalue_micro_version +LIBUNIVALUE_INTERFACE_AGE=libunivalue_interface_age + +# ABI version +# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html +LIBUNIVALUE_CURRENT=libunivalue_current +LIBUNIVALUE_REVISION=libunivalue_revision +LIBUNIVALUE_AGE=libunivalue_age + +AC_SUBST(LIBUNIVALUE_CURRENT) +AC_SUBST(LIBUNIVALUE_REVISION) +AC_SUBST(LIBUNIVALUE_AGE) + +LT_INIT +LT_LANG([C++]) + +case $host in + *mingw*) + LIBTOOL_APP_LDFLAGS="$LIBTOOL_APP_LDFLAGS -all-static" + ;; +esac + +BUILD_EXEEXT= +case $build in + *mingw*) + BUILD_EXEEXT=".exe" + ;; +esac + +AC_CONFIG_FILES([ + Makefile + pc/libunivalue.pc + pc/libunivalue-uninstalled.pc]) + +AC_SUBST(LIBTOOL_APP_LDFLAGS) +AC_SUBST(BUILD_EXEEXT) +AC_OUTPUT + diff --git a/src/univalue/gen.cpp b/src/univalue/gen/gen.cpp index 5e5a4d4aed..5e5a4d4aed 100644 --- a/src/univalue/gen.cpp +++ b/src/univalue/gen/gen.cpp diff --git a/src/univalue/univalue.h b/src/univalue/include/univalue.h index 4742b56f3d..ac05116011 100644 --- a/src/univalue/univalue.h +++ b/src/univalue/include/univalue.h @@ -1,11 +1,13 @@ // 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. -#ifndef BITCOIN_UNIVALUE_UNIVALUE_H -#define BITCOIN_UNIVALUE_UNIVALUE_H +#ifndef __UNIVALUE_H__ +#define __UNIVALUE_H__ #include <stdint.h> + #include <string> #include <vector> #include <map> @@ -245,4 +247,4 @@ extern const UniValue NullUniValue; const UniValue& find_value( const UniValue& obj, const std::string& name); -#endif // BITCOIN_UNIVALUE_UNIVALUE_H +#endif // __UNIVALUE_H__
\ No newline at end of file diff --git a/src/univalue/lib/.gitignore b/src/univalue/lib/.gitignore new file mode 100644 index 0000000000..ee7fc2851c --- /dev/null +++ b/src/univalue/lib/.gitignore @@ -0,0 +1,2 @@ +gen +.libs diff --git a/src/univalue/univalue.cpp b/src/univalue/lib/univalue.cpp index 1d49a2cfc9..883e8651fe 100644 --- a/src/univalue/univalue.cpp +++ b/src/univalue/lib/univalue.cpp @@ -1,16 +1,78 @@ // 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 <stdint.h> #include <ctype.h> +#include <errno.h> #include <iomanip> +#include <limits> #include <sstream> -#include <stdexcept> // std::runtime_error +#include <stdexcept> +#include <stdlib.h> +#include <string.h> #include "univalue.h" -#include "utilstrencodings.h" // ParseXX +namespace +{ +static bool ParsePrechecks(const std::string& str) +{ + if (str.empty()) // No empty string allowed + return false; + if (str.size() >= 1 && (isspace(str[0]) || 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<int32_t>::min() && + n <= std::numeric_limits<int32_t>::max(); +} + +bool ParseInt64(const std::string& str, int64_t *out) +{ + if (!ParsePrechecks(str)) + return false; + char *endp = 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<int64_t>::min() && + n <= std::numeric_limits<int64_t>::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; diff --git a/src/univalue/univalue_escapes.h b/src/univalue/lib/univalue_escapes.h index 4133b24ca1..4133b24ca1 100644 --- a/src/univalue/univalue_escapes.h +++ b/src/univalue/lib/univalue_escapes.h diff --git a/src/univalue/univalue_read.cpp b/src/univalue/lib/univalue_read.cpp index 261771811d..64591234cb 100644 --- a/src/univalue/univalue_read.cpp +++ b/src/univalue/lib/univalue_read.cpp @@ -244,16 +244,16 @@ bool UniValue::read(const char *raw) bool expectColon = false; vector<UniValue*> stack; + string tokenVal; + unsigned int consumed; enum jtokentype tok = JTOK_NONE; enum jtokentype last_tok = JTOK_NONE; - while (1) { + do { last_tok = tok; - string tokenVal; - unsigned int consumed; tok = getJsonToken(tokenVal, consumed, raw); if (tok == JTOK_NONE || tok == JTOK_ERR) - break; + return false; raw += consumed; switch (tok) { @@ -377,9 +377,11 @@ bool UniValue::read(const char *raw) default: return false; } - } + } while (!stack.empty ()); - if (stack.size() != 0) + /* Check that nothing follows the initial construct (parsed above). */ + tok = getJsonToken(tokenVal, consumed, raw); + if (tok != JTOK_NONE) return false; return true; diff --git a/src/univalue/univalue_write.cpp b/src/univalue/lib/univalue_write.cpp index bce3997af7..bce3997af7 100644 --- a/src/univalue/univalue_write.cpp +++ b/src/univalue/lib/univalue_write.cpp diff --git a/src/univalue/pc/libunivalue-uninstalled.pc.in b/src/univalue/pc/libunivalue-uninstalled.pc.in new file mode 100644 index 0000000000..b7f53e875e --- /dev/null +++ b/src/univalue/pc/libunivalue-uninstalled.pc.in @@ -0,0 +1,9 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libunivalue +Description: libunivalue, C++ universal value object and JSON library +Version: @VERSION@ +Libs: ${pc_top_builddir}/${pcfiledir}/libunivalue.la diff --git a/src/univalue/pc/libunivalue.pc.in b/src/univalue/pc/libunivalue.pc.in new file mode 100644 index 0000000000..358a2d5f73 --- /dev/null +++ b/src/univalue/pc/libunivalue.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libunivalue +Description: libunivalue, C++ universal value object and JSON library +Version: @VERSION@ +Libs: -L${libdir} -lunivalue +Cflags: -I${includedir} diff --git a/src/univalue/test/.gitignore b/src/univalue/test/.gitignore new file mode 100644 index 0000000000..4afa094b10 --- /dev/null +++ b/src/univalue/test/.gitignore @@ -0,0 +1 @@ +unitester diff --git a/src/univalue/test/fail1.json b/src/univalue/test/fail1.json new file mode 100644 index 0000000000..6216b865f1 --- /dev/null +++ b/src/univalue/test/fail1.json @@ -0,0 +1 @@ +"A JSON payload should be an object or array, not a string."
\ No newline at end of file diff --git a/src/univalue/test/fail10.json b/src/univalue/test/fail10.json new file mode 100644 index 0000000000..5d8c0047bd --- /dev/null +++ b/src/univalue/test/fail10.json @@ -0,0 +1 @@ +{"Extra value after close": true} "misplaced quoted value"
\ No newline at end of file diff --git a/src/univalue/test/fail11.json b/src/univalue/test/fail11.json new file mode 100644 index 0000000000..76eb95b458 --- /dev/null +++ b/src/univalue/test/fail11.json @@ -0,0 +1 @@ +{"Illegal expression": 1 + 2}
\ No newline at end of file diff --git a/src/univalue/test/fail12.json b/src/univalue/test/fail12.json new file mode 100644 index 0000000000..77580a4522 --- /dev/null +++ b/src/univalue/test/fail12.json @@ -0,0 +1 @@ +{"Illegal invocation": alert()}
\ No newline at end of file diff --git a/src/univalue/test/fail13.json b/src/univalue/test/fail13.json new file mode 100644 index 0000000000..379406b59b --- /dev/null +++ b/src/univalue/test/fail13.json @@ -0,0 +1 @@ +{"Numbers cannot have leading zeroes": 013}
\ No newline at end of file diff --git a/src/univalue/test/fail14.json b/src/univalue/test/fail14.json new file mode 100644 index 0000000000..0ed366b38a --- /dev/null +++ b/src/univalue/test/fail14.json @@ -0,0 +1 @@ +{"Numbers cannot be hex": 0x14}
\ No newline at end of file diff --git a/src/univalue/test/fail15.json b/src/univalue/test/fail15.json new file mode 100644 index 0000000000..fc8376b605 --- /dev/null +++ b/src/univalue/test/fail15.json @@ -0,0 +1 @@ +["Illegal backslash escape: \x15"]
\ No newline at end of file diff --git a/src/univalue/test/fail16.json b/src/univalue/test/fail16.json new file mode 100644 index 0000000000..3fe21d4b53 --- /dev/null +++ b/src/univalue/test/fail16.json @@ -0,0 +1 @@ +[\naked]
\ No newline at end of file diff --git a/src/univalue/test/fail17.json b/src/univalue/test/fail17.json new file mode 100644 index 0000000000..62b9214aed --- /dev/null +++ b/src/univalue/test/fail17.json @@ -0,0 +1 @@ +["Illegal backslash escape: \017"]
\ No newline at end of file diff --git a/src/univalue/test/fail18.json b/src/univalue/test/fail18.json new file mode 100644 index 0000000000..edac92716f --- /dev/null +++ b/src/univalue/test/fail18.json @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]
\ No newline at end of file diff --git a/src/univalue/test/fail19.json b/src/univalue/test/fail19.json new file mode 100644 index 0000000000..3b9c46fa9a --- /dev/null +++ b/src/univalue/test/fail19.json @@ -0,0 +1 @@ +{"Missing colon" null}
\ No newline at end of file diff --git a/src/univalue/test/fail2.json b/src/univalue/test/fail2.json new file mode 100644 index 0000000000..6b7c11e5a5 --- /dev/null +++ b/src/univalue/test/fail2.json @@ -0,0 +1 @@ +["Unclosed array"
\ No newline at end of file diff --git a/src/univalue/test/fail20.json b/src/univalue/test/fail20.json new file mode 100644 index 0000000000..27c1af3e72 --- /dev/null +++ b/src/univalue/test/fail20.json @@ -0,0 +1 @@ +{"Double colon":: null}
\ No newline at end of file diff --git a/src/univalue/test/fail21.json b/src/univalue/test/fail21.json new file mode 100644 index 0000000000..62474573b2 --- /dev/null +++ b/src/univalue/test/fail21.json @@ -0,0 +1 @@ +{"Comma instead of colon", null}
\ No newline at end of file diff --git a/src/univalue/test/fail22.json b/src/univalue/test/fail22.json new file mode 100644 index 0000000000..a7752581bc --- /dev/null +++ b/src/univalue/test/fail22.json @@ -0,0 +1 @@ +["Colon instead of comma": false]
\ No newline at end of file diff --git a/src/univalue/test/fail23.json b/src/univalue/test/fail23.json new file mode 100644 index 0000000000..494add1ca1 --- /dev/null +++ b/src/univalue/test/fail23.json @@ -0,0 +1 @@ +["Bad value", truth]
\ No newline at end of file diff --git a/src/univalue/test/fail24.json b/src/univalue/test/fail24.json new file mode 100644 index 0000000000..caff239bfc --- /dev/null +++ b/src/univalue/test/fail24.json @@ -0,0 +1 @@ +['single quote']
\ No newline at end of file diff --git a/src/univalue/test/fail25.json b/src/univalue/test/fail25.json new file mode 100644 index 0000000000..8b7ad23e01 --- /dev/null +++ b/src/univalue/test/fail25.json @@ -0,0 +1 @@ +[" tab character in string "]
\ No newline at end of file diff --git a/src/univalue/test/fail26.json b/src/univalue/test/fail26.json new file mode 100644 index 0000000000..845d26a6a5 --- /dev/null +++ b/src/univalue/test/fail26.json @@ -0,0 +1 @@ +["tab\ character\ in\ string\ "]
\ No newline at end of file diff --git a/src/univalue/test/fail27.json b/src/univalue/test/fail27.json new file mode 100644 index 0000000000..6b01a2ca4a --- /dev/null +++ b/src/univalue/test/fail27.json @@ -0,0 +1,2 @@ +["line +break"]
\ No newline at end of file diff --git a/src/univalue/test/fail28.json b/src/univalue/test/fail28.json new file mode 100644 index 0000000000..621a0101c6 --- /dev/null +++ b/src/univalue/test/fail28.json @@ -0,0 +1,2 @@ +["line\ +break"]
\ No newline at end of file diff --git a/src/univalue/test/fail29.json b/src/univalue/test/fail29.json new file mode 100644 index 0000000000..47ec421bb6 --- /dev/null +++ b/src/univalue/test/fail29.json @@ -0,0 +1 @@ +[0e]
\ No newline at end of file diff --git a/src/univalue/test/fail3.json b/src/univalue/test/fail3.json new file mode 100644 index 0000000000..168c81eb78 --- /dev/null +++ b/src/univalue/test/fail3.json @@ -0,0 +1 @@ +{unquoted_key: "keys must be quoted"}
\ No newline at end of file diff --git a/src/univalue/test/fail30.json b/src/univalue/test/fail30.json new file mode 100644 index 0000000000..8ab0bc4b8b --- /dev/null +++ b/src/univalue/test/fail30.json @@ -0,0 +1 @@ +[0e+]
\ No newline at end of file diff --git a/src/univalue/test/fail31.json b/src/univalue/test/fail31.json new file mode 100644 index 0000000000..1cce602b51 --- /dev/null +++ b/src/univalue/test/fail31.json @@ -0,0 +1 @@ +[0e+-1]
\ No newline at end of file diff --git a/src/univalue/test/fail32.json b/src/univalue/test/fail32.json new file mode 100644 index 0000000000..45cba7396f --- /dev/null +++ b/src/univalue/test/fail32.json @@ -0,0 +1 @@ +{"Comma instead if closing brace": true,
\ No newline at end of file diff --git a/src/univalue/test/fail33.json b/src/univalue/test/fail33.json new file mode 100644 index 0000000000..ca5eb19dc9 --- /dev/null +++ b/src/univalue/test/fail33.json @@ -0,0 +1 @@ +["mismatch"}
\ No newline at end of file diff --git a/src/univalue/test/fail34.json b/src/univalue/test/fail34.json new file mode 100644 index 0000000000..3f8be17286 --- /dev/null +++ b/src/univalue/test/fail34.json @@ -0,0 +1 @@ +{} garbage
\ No newline at end of file diff --git a/src/univalue/test/fail4.json b/src/univalue/test/fail4.json new file mode 100644 index 0000000000..9de168bf34 --- /dev/null +++ b/src/univalue/test/fail4.json @@ -0,0 +1 @@ +["extra comma",]
\ No newline at end of file diff --git a/src/univalue/test/fail5.json b/src/univalue/test/fail5.json new file mode 100644 index 0000000000..ddf3ce3d24 --- /dev/null +++ b/src/univalue/test/fail5.json @@ -0,0 +1 @@ +["double extra comma",,]
\ No newline at end of file diff --git a/src/univalue/test/fail6.json b/src/univalue/test/fail6.json new file mode 100644 index 0000000000..ed91580e1b --- /dev/null +++ b/src/univalue/test/fail6.json @@ -0,0 +1 @@ +[ , "<-- missing value"]
\ No newline at end of file diff --git a/src/univalue/test/fail7.json b/src/univalue/test/fail7.json new file mode 100644 index 0000000000..8a96af3e4e --- /dev/null +++ b/src/univalue/test/fail7.json @@ -0,0 +1 @@ +["Comma after the close"],
\ No newline at end of file diff --git a/src/univalue/test/fail8.json b/src/univalue/test/fail8.json new file mode 100644 index 0000000000..b28479c6ec --- /dev/null +++ b/src/univalue/test/fail8.json @@ -0,0 +1 @@ +["Extra close"]]
\ No newline at end of file diff --git a/src/univalue/test/fail9.json b/src/univalue/test/fail9.json new file mode 100644 index 0000000000..5815574f36 --- /dev/null +++ b/src/univalue/test/fail9.json @@ -0,0 +1 @@ +{"Extra comma": true,}
\ No newline at end of file diff --git a/src/univalue/test/pass1.json b/src/univalue/test/pass1.json new file mode 100644 index 0000000000..70e2685436 --- /dev/null +++ b/src/univalue/test/pass1.json @@ -0,0 +1,58 @@ +[ + "JSON Test Pattern pass1", + {"object with 1 member":["array with 1 element"]}, + {}, + [], + -42, + true, + false, + null, + { + "integer": 1234567890, + "real": -9876.543210, + "e": 0.123456789e-12, + "E": 1.234567890E+34, + "": 23456789012E66, + "zero": 0, + "one": 1, + "space": " ", + "quote": "\"", + "backslash": "\\", + "controls": "\b\f\n\r\t", + "slash": "/ & \/", + "alpha": "abcdefghijklmnopqrstuvwyz", + "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ", + "digit": "0123456789", + "0123456789": "digit", + "special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?", + "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A", + "true": true, + "false": false, + "null": null, + "array":[ ], + "object":{ }, + "address": "50 St. James Street", + "url": "http://www.JSON.org/", + "comment": "// /* <!-- --", + "# -- --> */": " ", + " s p a c e d " :[1,2 , 3 + +, + +4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7], + "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}", + "quotes": "" \u0022 %22 0x22 034 "", + "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?" +: "A key can be any string" + }, + 0.5 ,98.6 +, +99.44 +, + +1066, +1e1, +0.1e1, +1e-1, +1e00,2e+00,2e-00 +,"rosebud"]
\ No newline at end of file diff --git a/src/univalue/test/pass2.json b/src/univalue/test/pass2.json new file mode 100644 index 0000000000..d3c63c7ad8 --- /dev/null +++ b/src/univalue/test/pass2.json @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]
\ No newline at end of file diff --git a/src/univalue/test/pass3.json b/src/univalue/test/pass3.json new file mode 100644 index 0000000000..4528d51f1a --- /dev/null +++ b/src/univalue/test/pass3.json @@ -0,0 +1,6 @@ +{ + "JSON Test Pattern pass3": { + "The outermost value": "must be an object or array.", + "In this test": "It is an object." + } +} diff --git a/src/univalue/test/unitester.cpp b/src/univalue/test/unitester.cpp new file mode 100644 index 0000000000..835556e031 --- /dev/null +++ b/src/univalue/test/unitester.cpp @@ -0,0 +1,115 @@ +// Copyright 2014 BitPay Inc. +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <cassert> +#include <string> +#include "univalue.h" + +#ifndef JSON_TEST_SRC +#error JSON_TEST_SRC must point to test source directory +#endif + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +#endif + +using namespace std; +string srcdir(JSON_TEST_SRC); + +static void runtest(string filename, const string& jdata) +{ + fprintf(stderr, "test %s\n", filename.c_str()); + + string prefix = filename.substr(0, 4); + + bool wantPass = (prefix == "pass"); + bool wantFail = (prefix == "fail"); + assert(wantPass || wantFail); + + UniValue val; + bool testResult = val.read(jdata); + + if (wantPass) { + assert(testResult == true); + } else { + assert(testResult == false); + } +} + +static void runtest_file(const char *filename_) +{ + string basename(filename_); + string filename = srcdir + "/" + basename; + FILE *f = fopen(filename.c_str(), "r"); + assert(f != NULL); + + string jdata; + + char buf[4096]; + while (!feof(f)) { + int bread = fread(buf, 1, sizeof(buf), f); + assert(!ferror(f)); + + string s(buf, bread); + jdata += s; + } + + assert(!ferror(f)); + fclose(f); + + 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", + "fail3.json", + "fail4.json", // extra comma + "fail5.json", + "fail6.json", + "fail7.json", + "fail8.json", + "fail9.json", // extra comma + "pass1.json", + "pass2.json", + "pass3.json", +}; + +int main (int argc, char *argv[]) +{ + for (unsigned int fidx = 0; fidx < ARRAY_SIZE(filenames); fidx++) { + runtest_file(filenames[fidx]); + } + + return 0; +} + |