diff --git a/.gitignore b/.gitignore index 6dfd3fd10a..c3b5f804e8 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,8 @@ /depcomp /install-sh /json.pc +/json-c.pc +/json-c-uninstalled.pc /libtool /ltmain.sh /Makefile @@ -36,4 +38,5 @@ /Release *.lo *.o +/libjson-c.la /libjson.la diff --git a/Android.configure.mk b/Android.configure.mk new file mode 100644 index 0000000000..a6265adac8 --- /dev/null +++ b/Android.configure.mk @@ -0,0 +1,39 @@ +# This file is the top android makefile for all sub-modules. + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +json_c_TOP := $(LOCAL_PATH) + +JSON_C_BUILT_SOURCES := Android.mk + +JSON_C_BUILT_SOURCES := $(patsubst %, $(abspath $(json_c_TOP))/%, $(JSON_C_BUILT_SOURCES)) + +.PHONY: json-c-configure json-c-configure-real +json-c-configure-real: + echo $(JSON_C_BUILT_SOURCES) + cd $(json_c_TOP) ; \ + $(abspath $(json_c_TOP))/autogen.sh && \ + CC="$(CONFIGURE_CC)" \ + CFLAGS="$(CONFIGURE_CFLAGS)" \ + LD=$(TARGET_LD) \ + LDFLAGS="$(CONFIGURE_LDFLAGS)" \ + CPP=$(CONFIGURE_CPP) \ + CPPFLAGS="$(CONFIGURE_CPPFLAGS)" \ + PKG_CONFIG_LIBDIR=$(CONFIGURE_PKG_CONFIG_LIBDIR) \ + PKG_CONFIG_TOP_BUILD_DIR=/ \ + ac_cv_func_malloc_0_nonnull=yes \ + ac_cv_func_realloc_0_nonnull=yes \ + $(abspath $(json_c_TOP))/$(CONFIGURE) --host=$(CONFIGURE_HOST) \ + --prefix=/system \ + && \ + for file in $(JSON_C_BUILT_SOURCES); do \ + rm -f $$file && \ + make -C $$(dirname $$file) $$(basename $$file) ; \ + done + +json-c-configure: json-c-configure-real + +PA_CONFIGURE_TARGETS += json-c-configure + +-include $(json_c_TOP)/Android.mk diff --git a/ChangeLog b/ChangeLog index e0fd4a3e78..42a3da9982 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ + +NEXT.VERSION + + * IMPORTANT: the name of the library has changed to libjson-c.so and + the header files are now in include/json-c. + The pkgconfig name has also changed from json to json-c. + You should change your build to use appropriate -I and -l options. + A compatibility shim is in place so builds using the old name will + continue to work, but that will be removed in the next release. + 0.10 * Add a json_object_to_json_string_ext() function to allow output to be diff --git a/Makefile.am b/Makefile.am index d4a7bbbe4f..09221a3852 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,13 +3,19 @@ include Makefile.am.inc EXTRA_DIST = README.html README-WIN32.html config.h.win32 doc json-c.vcproj SUBDIRS = . tests -lib_LTLIBRARIES = libjson.la +lib_LTLIBRARIES = libjson-c.la +if ENABLE_OLDNAME_COMPAT +lib_LTLIBRARIES+=libjson.la +endif pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = json.pc +pkgconfig_DATA = json-c.pc +if ENABLE_OLDNAME_COMPAT +pkgconfig_DATA += json.pc +endif -libjsonincludedir = $(includedir)/json -libjsoninclude_HEADERS = \ +libjson_cincludedir = $(includedir)/json-c +libjson_cinclude_HEADERS = \ arraylist.h \ bits.h \ debug.h \ @@ -17,6 +23,7 @@ libjsoninclude_HEADERS = \ json_config.h \ json_inttypes.h \ json_object.h \ + json_object_iterator.h \ json_object_private.h \ json_tokener.h \ json_util.h \ @@ -28,9 +35,17 @@ libjsoninclude_HEADERS = \ #libjsonx_include_HEADERS = \ # json_config.h -libjson_la_LDFLAGS = -version-info 1:0:1 -no-undefined +libjson_c_la_LDFLAGS = -version-info 2:0:0 -no-undefined -libjson_la_SOURCES = \ +if ENABLE_OLDNAME_COMPAT +libjson_la_LDFLAGS = -version-info 1:0:1 -no-undefined -ljson-c + +# Temporary libjson library. This will be removed after one release. +libjson_la_LIBADD = -ljson-c +endif + + +libjson_c_la_SOURCES = \ arraylist.c \ debug.c \ json_object.c \ @@ -44,3 +59,28 @@ distclean-local: -rm -rf $(testsubdir) -rm -rf config.h.in~ Makefile.in aclocal.m4 autom4te.cache/ config.guess config.sub configure depcomp install-sh ltmain.sh missing +if ENABLE_OLDNAME_COMPAT +install-data-hook: + test \! -d "$(includedir)/json" || rmdir "$(includedir)/json" + test \! -e "$(includedir)/json" || rm "$(includedir)/json" + $(LN_S) json-c "$(includedir)/json" + +uninstall-local: + rm -f "$(includedir)/json" + +endif + +ANDROID_CFLAGS = -I$(top_srcdir) -DHAVE_CONFIG_H + +Android.mk: Makefile.am + androgenizer -:PROJECT json-c \ + -:SHARED libjson-c \ + -:TAGS eng debug \ + -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \ + -:SOURCES $(libjson_c_la_SOURCES) $(nodist_libjson_c_la_SOURCES) \ + -:CFLAGS $(DEFS) $(ANDROID_CFLAGS) $(libjson_c_la_CFLAGS) \ + -:LDFLAGS $(libjson_c_la_LDFLAGS) $(libjson_c_la_LIBADD) \ + -:HEADER_TARGET json-c \ + -:HEADERS $(libjson_cinclude_HEADERS) \ + -:PASSTHROUGH LOCAL_ARM_MODE:=arm \ + > $@ diff --git a/README b/README index 05ec274418..20adddcc9f 100644 --- a/README +++ b/README @@ -3,6 +3,8 @@ Building on Unix with git, gcc and autotools Home page for json-c: http://oss.metaparadigm.com/json-c/ + Caution: do NOT use sources from svn.metaparadigm.com, they are old. + Github repo for json-c: https://github.com/json-c/json-c @@ -20,9 +22,15 @@ To build and run the test programs run $ make check -Linking to libjson +Linking to libjson-c If your system has pkgconfig then you can just add this to your makefile -CFLAGS += $(shell pkg-config --cflags json) -LDFLAGS += $(shell pkg-config --libs json) +CFLAGS += $(shell pkg-config --cflags json-c) +LDFLAGS += $(shell pkg-config --libs json-c) + +Without pkgconfig, you would do something like this: + +JSON_C_DIR=/path/to/json_c/install +CFLAGS += -I$(JSON_C_DIR)/include/json-c +LDFLAGS+= -L$(JSON_C_DIR)/lib -ljson-c diff --git a/RELEASE_CHECKLIST.txt b/RELEASE_CHECKLIST.txt index 28f5b89a00..1eccac89e5 100644 --- a/RELEASE_CHECKLIST.txt +++ b/RELEASE_CHECKLIST.txt @@ -34,11 +34,13 @@ echo autom4te.cache >> excludes tar -czf json-c-${release}.tar.gz -X excludes json-c-${release} echo doc >> excludes -tar -czf json-c-${release}-doc.tar.gz -X excludes json-c-${release} +tar -czf json-c-${release}-nodoc.tar.gz -X excludes json-c-${release} Tag the branch: cd json-c-${release} -git tag json-c-${release}-$(date +%Y%m%d) +git tag -a json-c-${release}-$(date +%Y%m%d) +git push +git push --tags Go to https://github.com/json-c/json-c/downloads Upload the two tarballs. diff --git a/arraylist.c b/arraylist.c index 9a673d6756..81b6fa2b64 100644 --- a/arraylist.c +++ b/arraylist.c @@ -11,12 +11,12 @@ #include "config.h" -#if STDC_HEADERS +#ifdef STDC_HEADERS # include # include #endif /* STDC_HEADERS */ -#if defined HAVE_STRINGS_H && !defined _STRING_H && !defined __USE_BSD +#if defined(HAVE_STRINGS_H) && !defined(_STRING_H) && !defined(__USE_BSD) # include #endif /* HAVE_STRINGS_H */ @@ -74,7 +74,7 @@ static int array_list_expand_internal(struct array_list *arr, int max) int array_list_put_idx(struct array_list *arr, int idx, void *data) { - if(array_list_expand_internal(arr, idx)) return -1; + if(array_list_expand_internal(arr, idx+1)) return -1; if(arr->array[idx]) arr->free_fn(arr->array[idx]); arr->array[idx] = data; if(arr->length <= idx) arr->length = idx + 1; diff --git a/autogen.sh b/autogen.sh index c67b9034d5..69e765a602 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1 +1,13 @@ +#!/bin/sh autoreconf -v --install || exit 1 + +# If there are any options, assume the user wants to run configure. +# To run configure w/o any options, use ./autogen.sh --configure +if [ $# -gt 0 ] ; then + case "$1" in + --conf*) + shift 1 + ;; + esac + exec ./configure "$@" +fi diff --git a/config.h.in b/config.h.in index 04f5dc5f8e..34ad9a8442 100644 --- a/config.h.in +++ b/config.h.in @@ -29,6 +29,9 @@ and to 0 otherwise. */ #undef HAVE_REALLOC +/* Define to 1 if you have the `snprintf' function. */ +#undef HAVE_SNPRINTF + /* Define to 1 if you have the header file. */ #undef HAVE_STDARG_H @@ -38,6 +41,12 @@ /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H +/* Define to 1 if you have the `strcasecmp' function. */ +#undef HAVE_STRCASECMP + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRDUP + /* Define to 1 if you have the `strerror' function. */ #undef HAVE_STRERROR @@ -56,6 +65,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYSLOG_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_CDEFS_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PARAM_H diff --git a/configure.in b/configure.in index b2c3cbee02..5b2eea3d37 100644 --- a/configure.in +++ b/configure.in @@ -7,6 +7,14 @@ AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION) AC_PROG_MAKE_SET +AC_ARG_ENABLE(oldname-compat, + AS_HELP_STRING([--disable-oldname-compat], + [Don't include the old libjson.so library and include/json directory.]), +[], +[enable_oldname_compat=yes] +) +AM_CONDITIONAL(ENABLE_OLDNAME_COMPAT, [test "x${enable_oldname_compat}" != "xno"]) + # Checks for programs. # Checks for libraries. @@ -15,7 +23,7 @@ AC_PROG_MAKE_SET AM_CONFIG_HEADER(config.h) AM_CONFIG_HEADER(json_config.h) AC_HEADER_STDC -AC_CHECK_HEADERS(fcntl.h limits.h strings.h syslog.h unistd.h [sys/param.h] stdarg.h) +AC_CHECK_HEADERS(fcntl.h limits.h strings.h syslog.h unistd.h [sys/cdefs.h] [sys/param.h] stdarg.h) AC_CHECK_HEADER(inttypes.h,[AC_DEFINE([JSON_C_HAVE_INTTYPES_H],[1],[Public define for json_inttypes.h])]) # Checks for typedefs, structures, and compiler characteristics. @@ -27,14 +35,16 @@ AC_FUNC_VPRINTF AC_FUNC_MEMCMP AC_FUNC_MALLOC AC_FUNC_REALLOC -AC_CHECK_FUNCS(strndup strerror vsnprintf vasprintf open vsyslog strncasecmp) +AC_CHECK_FUNCS(strcasecmp strdup strndup strerror snprintf vsnprintf vasprintf open vsyslog strncasecmp) AM_PROG_LIBTOOL AC_CONFIG_FILES([ Makefile json.pc +json-c.pc tests/Makefile +json-c-uninstalled.pc ]) AC_OUTPUT diff --git a/json-c-uninstalled.pc.in b/json-c-uninstalled.pc.in new file mode 100644 index 0000000000..dab2bab5ce --- /dev/null +++ b/json-c-uninstalled.pc.in @@ -0,0 +1,11 @@ +prefix= +exec_prefix= +libdir=@abs_top_builddir@ +includedir=@abs_top_srcdir@ + +Name: json +Description: JSON implementation in C +Version: @VERSION@ +Requires: +Libs: -L@abs_top_builddir@ -ljson-c +Cflags: -I@abs_top_srcdir@ diff --git a/json-c.pc.in b/json-c.pc.in new file mode 100644 index 0000000000..037739d27b --- /dev/null +++ b/json-c.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: json-c +Description: JSON implementation in C +Version: @VERSION@ +Requires: +Libs: -L${libdir} -ljson-c +Cflags: -I${includedir}/json-c diff --git a/json.pc.in b/json.pc.in index b3d140be97..80e75d141a 100644 --- a/json.pc.in +++ b/json.pc.in @@ -3,9 +3,9 @@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ -Name: json -Description: JSON implementation in C +Name: json-c +Description: JSON implementation in C, compat shim. Use json-c instead. Version: @VERSION@ -Requires: -Libs: -L${libdir} -ljson -Cflags: -I${includedir}/json +Requires: json-c +Libs: +Cflags: diff --git a/json_object.c b/json_object.c index 5a359381d9..8dd13b0d66 100644 --- a/json_object.c +++ b/json_object.c @@ -26,7 +26,14 @@ #include "json_object_private.h" #include "json_util.h" -#if !HAVE_STRNDUP +#if !defined(HAVE_STRDUP) && defined(_MSC_VER) + /* MSC has the version as _strdup */ +# define strdup _strdup +#elif !defined(HAVE_STRDUP) +# error You do not have strdup on your system. +#endif /* HAVE_STRDUP */ + +#if !defined(HAVE_STRNDUP) char* strndup(const char* str, size_t n); #endif /* !HAVE_STRNDUP */ @@ -299,8 +306,20 @@ struct lh_table* json_object_get_object(struct json_object *jso) void json_object_object_add(struct json_object* jso, const char *key, struct json_object *val) { - lh_table_delete(jso->o.c_object, key); - lh_table_insert(jso->o.c_object, strdup(key), val); + // We lookup the entry and replace the value, rather than just deleting + // and re-adding it, so the existing key remains valid. + json_object *existing_value = NULL; + struct lh_entry *existing_entry; + existing_entry = lh_table_lookup_entry(jso->o.c_object, (void*)key); + if (!existing_entry) + { + lh_table_insert(jso->o.c_object, strdup(key), val); + return; + } + existing_value = (void *)existing_entry->v; + if (existing_value) + json_object_put(existing_value); + existing_entry->v = val; } struct json_object* json_object_object_get(struct json_object* jso, const char *key) @@ -531,7 +550,7 @@ struct json_object* json_object_new_string_len(const char *s, int len) if(!jso) return NULL; jso->_delete = &json_object_string_delete; jso->_to_json_string = &json_object_string_to_json_string; - jso->o.c_string.str = malloc(len); + jso->o.c_string.str = (char*)malloc(len); memcpy(jso->o.c_string.str, (void *)s, len); jso->o.c_string.len = len; return jso; diff --git a/json_tokener.c b/json_tokener.c index 1c8248472e..f5fa8d6030 100644 --- a/json_tokener.c +++ b/json_tokener.c @@ -31,6 +31,13 @@ #include "json_tokener.h" #include "json_util.h" +#if !HAVE_STRDUP && defined(_MSC_VER) + /* MSC has the version as _strdup */ +# define strdup _strdup +#elif !HAVE_STRDUP +# error You do not have strdup on your system. +#endif /* HAVE_STRDUP */ + #if !HAVE_STRNCASECMP && defined(_MSC_VER) /* MSC has the version as _strnicmp */ # define strncasecmp _strnicmp @@ -38,7 +45,6 @@ # error You do not have strncasecmp on your system. #endif /* HAVE_STRNCASECMP */ - static const char* json_null_str = "null"; static const char* json_true_str = "true"; static const char* json_false_str = "false"; @@ -417,10 +423,12 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok, case 'n': case 'r': case 't': + case 'f': if(c == 'b') printbuf_memappend_fast(tok->pb, "\b", 1); else if(c == 'n') printbuf_memappend_fast(tok->pb, "\n", 1); else if(c == 'r') printbuf_memappend_fast(tok->pb, "\r", 1); else if(c == 't') printbuf_memappend_fast(tok->pb, "\t", 1); + else if(c == 'f') printbuf_memappend_fast(tok->pb, "\f", 1); state = saved_state; break; case 'u': diff --git a/json_util.c b/json_util.c index e551d2dbb0..79ae5c7071 100644 --- a/json_util.c +++ b/json_util.c @@ -20,19 +20,19 @@ #include #include -#if HAVE_SYS_TYPES_H +#ifdef HAVE_SYS_TYPES_H #include #endif /* HAVE_SYS_TYPES_H */ -#if HAVE_SYS_STAT_H +#ifdef HAVE_SYS_STAT_H #include #endif /* HAVE_SYS_STAT_H */ -#if HAVE_FCNTL_H +#ifdef HAVE_FCNTL_H #include #endif /* HAVE_FCNTL_H */ -#if HAVE_UNISTD_H +#ifdef HAVE_UNISTD_H # include #endif /* HAVE_UNISTD_H */ @@ -42,10 +42,16 @@ # include #endif /* defined(WIN32) */ -#if !HAVE_OPEN && defined(WIN32) +#if !defined(HAVE_OPEN) && defined(WIN32) # define open _open #endif +#if !defined(HAVE_SNPRINTF) && defined(_MSC_VER) + /* MSC has the version as _snprintf */ +# define snprintf _snprintf +#elif !defined(HAVE_SNPRINTF) +# error You do not have snprintf on your system. +#endif /* HAVE_SNPRINTF */ #include "bits.h" #include "debug.h" @@ -65,7 +71,7 @@ struct json_object* json_object_from_file(const char *filename) if((fd = open(filename, O_RDONLY)) < 0) { MC_ERROR("json_object_from_file: error reading file %s: %s\n", filename, strerror(errno)); - return NULL; // XAX this is an API change! + return NULL; } if(!(pb = printbuf_new())) { close(fd); @@ -141,11 +147,14 @@ int json_parse_int64(const char *buf, int64_t *retval) int64_t num64; const char *buf_skip_space; int orig_has_neg; + int _errno; + errno = 0; // sscanf won't always set errno, so initialize if (sscanf(buf, "%" SCNd64, &num64) != 1) { MC_DEBUG("Failed to parse, sscanf != 1\n"); return 1; } + _errno = errno; buf_skip_space = buf; orig_has_neg = 0; // Skip leading spaces @@ -162,7 +171,7 @@ int json_parse_int64(const char *buf, int64_t *retval) if (buf_skip_space[0] == '0' && buf_skip_space[1] == '\0') orig_has_neg = 0; // "-0" is the same as just plain "0" - if (errno != ERANGE) + if (_errno != ERANGE) { char buf_cmp[100]; char *buf_cmp_start = buf_cmp; @@ -190,10 +199,10 @@ int json_parse_int64(const char *buf, int64_t *retval) ) ) { - errno = ERANGE; + _errno = ERANGE; } } - if (errno == ERANGE) + if (_errno == ERANGE) { if (orig_has_neg) num64 = INT64_MIN; @@ -204,7 +213,7 @@ int json_parse_int64(const char *buf, int64_t *retval) return 0; } -#if HAVE_REALLOC == 0 +#ifndef HAVE_REALLOC void* rpl_realloc(void* p, size_t n) { if (n == 0) diff --git a/libjson.c b/libjson.c new file mode 100644 index 0000000000..48fc3a4b3e --- /dev/null +++ b/libjson.c @@ -0,0 +1,27 @@ + +/* dummy source file for compatibility purposes */ + +#if defined(HAVE_CDEFS_H) +#include +#endif + +#ifndef __warn_references + +#ifdef __GNUC__ +#define __warn_references(sym,msg) \ + __asm(".pushsection .gnu.warning." #sym "\n" \ + ".ascii \"" msg "\"\n" \ + ".popsection"); + +#else +#define __warn_references(sym,msg) /* nothing */ +#endif + +#endif + +#include "json_object.h" + +__warn_references(json_object_get, "Warning: please link against libjson-c instead of libjson"); + +/* __asm__(".section .gnu.warning." __STRING(sym) \ + " ; .ascii \"" msg "\" ; .text") */ diff --git a/printbuf.c b/printbuf.c index b951c7b4f4..9d56522000 100644 --- a/printbuf.c +++ b/printbuf.c @@ -19,7 +19,7 @@ #include #include -#if HAVE_STDARG_H +#ifdef HAVE_STDARG_H # include #else /* !HAVE_STDARG_H */ # error Not enough var arg support! @@ -108,13 +108,13 @@ int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len) return 0; } -#if !HAVE_VSNPRINTF && defined(_MSC_VER) +#if !defined(HAVE_VSNPRINTF) && defined(_MSC_VER) # define vsnprintf _vsnprintf -#elif !HAVE_VSNPRINTF /* !HAVE_VSNPRINTF */ +#elif !defined(HAVE_VSNPRINTF) /* !HAVE_VSNPRINTF */ # error Need vsnprintf! #endif /* !HAVE_VSNPRINTF && defined(WIN32) */ -#if !HAVE_VASPRINTF +#if !defined(HAVE_VASPRINTF) /* CAW: compliant version of vasprintf */ static int vasprintf(char **buf, const char *fmt, va_list ap) { diff --git a/tests/Makefile.am b/tests/Makefile.am index e2854dd2db..635ce5583e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -6,6 +6,7 @@ LIBJSON_LA=$(top_builddir)/libjson.la check_PROGRAMS = test1 test1Formatted check_PROGRAMS += test2 test2Formatted check_PROGRAMS += test4 +check_PROGRAMS += testReplaceExisting check_PROGRAMS += test_parse_int64 check_PROGRAMS += test_null check_PROGRAMS += test_cast @@ -25,6 +26,8 @@ test2Formatted_CPPFLAGS = -DTEST_FORMATTED test4_LDADD = $(LIBJSON_LA) +testReplaceExisting_LDADD = $(LIBJSON_LA) + test_parse_int64_LDADD = $(LIBJSON_LA) test_null_LDADD = $(LIBJSON_LA) @@ -33,7 +36,7 @@ test_cast_LDADD = $(LIBJSON_LA) test_parse_LDADD = $(LIBJSON_LA) -TESTS = test1.test test2.test test4.test parse_int64.test test_null.test test_cast.test test_parse.test +TESTS = test1.test test2.test test4.test testReplaceExisting.test parse_int64.test test_null.test test_cast.test test_parse.test TESTS+= test_printbuf.test check_PROGRAMS+=test_printbuf diff --git a/tests/parse_flags.c b/tests/parse_flags.c index fafabc8f37..e33ffee3b8 100644 --- a/tests/parse_flags.c +++ b/tests/parse_flags.c @@ -1,9 +1,17 @@ +#include "config.h" + #include #include #include "json.h" #include "parse_flags.h" +#if !defined(HAVE_STRCASECMP) && defined(_MSC_VER) +# define strcasecmp _stricmp +#elif !defined(HAVE_STRCASECMP) +# error You do not have strcasecmp on your system. +#endif /* HAVE_STRNCASECMP */ + static struct { const char *arg; int flag; diff --git a/tests/test1.c b/tests/test1.c index 9802eb10d3..87d7ea47c3 100644 --- a/tests/test1.c +++ b/tests/test1.c @@ -12,8 +12,8 @@ static int sort_fn (const void *j1, const void *j2) json_object * const *jso1, * const *jso2; int i1, i2; - jso1 = j1; - jso2 = j2; + jso1 = (json_object* const*)j1; + jso2 = (json_object* const*)j2; if (!*jso1 && !*jso2) { return 0; } diff --git a/tests/testReplaceExisting.c b/tests/testReplaceExisting.c new file mode 100644 index 0000000000..8c8c4b20aa --- /dev/null +++ b/tests/testReplaceExisting.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include + +#include "json.h" + +int main(int argc, char **argv) +{ + MC_SET_DEBUG(1); + + /* + * Check that replacing an existing object keeps the key valid, + * and that it keeps the order the same. + */ + json_object *my_object = json_object_new_object(); + json_object_object_add(my_object, "foo1", json_object_new_string("bar1")); + json_object_object_add(my_object, "foo2", json_object_new_string("bar2")); + json_object_object_add(my_object, "foo3", json_object_new_string("bar3")); + const char *original_key = NULL; + int orig_count = 0; + json_object_object_foreach(my_object, key, val) + { + printf("Key at index %d is [%s]\n", orig_count, key); + orig_count++; + if (strcmp(key, "foo2") != 0) + continue; + printf("replacing value for key [%s]\n", key); + original_key = key; + json_object_object_add(my_object, key, json_object_new_string("zzz")); + } + + printf("==== second loop starting ====\n"); + + int new_count = 0; + int retval = 0; + json_object_object_foreach(my_object, key2, val2) + { + printf("Key at index %d is [%s]\n", new_count, key2); + new_count++; + if (strcmp(key2, "foo2") != 0) + continue; + printf("pointer for key [%s] does %smatch\n", key2, + (key2 == original_key) ? "" : "NOT "); + if (key2 != original_key) + retval = 1; + } + if (new_count != orig_count) + { + printf("mismatch between original count (%d) and new count (%d)\n", + orig_count, new_count); + retval = 1; + } + + return 0; +} diff --git a/tests/testReplaceExisting.expected b/tests/testReplaceExisting.expected new file mode 100644 index 0000000000..4d1c509e31 --- /dev/null +++ b/tests/testReplaceExisting.expected @@ -0,0 +1,9 @@ +Key at index 0 is [foo1] +Key at index 1 is [foo2] +replacing value for key [foo2] +Key at index 2 is [foo3] +==== second loop starting ==== +Key at index 0 is [foo1] +Key at index 1 is [foo2] +pointer for key [foo2] does match +Key at index 2 is [foo3] diff --git a/tests/testReplaceExisting.test b/tests/testReplaceExisting.test new file mode 100755 index 0000000000..ec5cbf1916 --- /dev/null +++ b/tests/testReplaceExisting.test @@ -0,0 +1,12 @@ +#!/bin/sh + +# Common definitions +if test -z "$srcdir"; then + srcdir="${0%/*}" + test "$srcdir" = "$0" && srcdir=. + test -z "$srcdir" && srcdir=. +fi +. "$srcdir/test-defs.sh" + +run_output_test testReplaceExisting +exit $? diff --git a/tests/test_parse.c b/tests/test_parse.c index 0040760d76..975fb52cb9 100644 --- a/tests/test_parse.c +++ b/tests/test_parse.c @@ -166,6 +166,15 @@ struct incremental_step { /* Strings have a well defined end point, so we can stop at the quote */ { "\"blue\"", -1, -1, json_tokener_success, 0 }, + /* Check each of the escape sequences defined by the spec */ + { "\"\\\"\"", -1, -1, json_tokener_success, 0 }, + { "\"\\\\\"", -1, -1, json_tokener_success, 0 }, + { "\"\\b\"", -1, -1, json_tokener_success, 0 }, + { "\"\\f\"", -1, -1, json_tokener_success, 0 }, + { "\"\\n\"", -1, -1, json_tokener_success, 0 }, + { "\"\\r\"", -1, -1, json_tokener_success, 0 }, + { "\"\\t\"", -1, -1, json_tokener_success, 0 }, + { "[1,2,3]", -1, -1, json_tokener_success, 0 }, /* This behaviour doesn't entirely follow the json spec, but until we have @@ -190,6 +199,8 @@ static void test_incremental_parse() num_error = 0; printf("Starting incremental tests.\n"); + printf("Note: quotes and backslashes seen in the output here are literal values passed\n"); + printf(" to the parse functions. e.g. this is 4 characters: \"\\f\"\n"); string_to_parse = "{ \"foo"; /* } */ printf("json_tokener_parse(%s) ... ", string_to_parse); diff --git a/tests/test_parse.expected b/tests/test_parse.expected index 2481bdeaab..97910dc0ff 100644 --- a/tests/test_parse.expected +++ b/tests/test_parse.expected @@ -21,6 +21,8 @@ new_obj.to_string()={ "abc": 12, "foo": "bar", "bool0": false, "bool1": true, "a json_tokener_parse_versbose() OK ================================== Starting incremental tests. +Note: quotes and backslashes seen in the output here are literal values passed + to the parse functions. e.g. this is 4 characters: "\f" json_tokener_parse({ "foo) ... got error as expected json_tokener_parse_ex(tok, { "foo": 123 }, 14) ... OK: got object of type [object]: { "foo": 123 } json_tokener_parse_ex(tok, { "foo": 456 }, 14) ... OK: got object of type [object]: { "foo": 456 } @@ -39,8 +41,15 @@ json_tokener_parse_ex(tok, "Y" , 3) ... OK: got object of type [string json_tokener_parse_ex(tok, 1 , 1) ... OK: got correct error: continue json_tokener_parse_ex(tok, 2 , 2) ... OK: got object of type [int]: 12 json_tokener_parse_ex(tok, "blue" , 6) ... OK: got object of type [string]: "blue" +json_tokener_parse_ex(tok, "\"" , 4) ... OK: got object of type [string]: "\"" +json_tokener_parse_ex(tok, "\\" , 4) ... OK: got object of type [string]: "\\" +json_tokener_parse_ex(tok, "\b" , 4) ... OK: got object of type [string]: "\b" +json_tokener_parse_ex(tok, "\f" , 4) ... OK: got object of type [string]: "\u000c" +json_tokener_parse_ex(tok, "\n" , 4) ... OK: got object of type [string]: "\n" +json_tokener_parse_ex(tok, "\r" , 4) ... OK: got object of type [string]: "\r" +json_tokener_parse_ex(tok, "\t" , 4) ... OK: got object of type [string]: "\t" json_tokener_parse_ex(tok, [1,2,3] , 7) ... OK: got object of type [array]: [ 1, 2, 3 ] json_tokener_parse_ex(tok, [1,2,3,] , 8) ... OK: got object of type [array]: [ 1, 2, 3 ] json_tokener_parse_ex(tok, [1,2,,3,] , 9) ... OK: got correct error: unexpected character -End Incremental Tests OK=20 ERROR=0 +End Incremental Tests OK=27 ERROR=0 ================================== diff --git a/tests/test_parse_int64.c b/tests/test_parse_int64.c index 08933568d4..c251e01348 100644 --- a/tests/test_parse_int64.c +++ b/tests/test_parse_int64.c @@ -80,6 +80,9 @@ int main() strcpy(buf, "-21474836480"); // INT32_MIN * 10 checkit(buf); + strcpy(buf, "9223372036854775806"); // INT64_MAX - 1 + checkit(buf); + strcpy(buf, "9223372036854775807"); // INT64_MAX checkit(buf); @@ -92,6 +95,9 @@ int main() strcpy(buf, "-9223372036854775809"); // INT64_MIN - 1 checkit(buf); + strcpy(buf, "18446744073709551614"); // UINT64_MAX - 1 + checkit(buf); + strcpy(buf, "18446744073709551615"); // UINT64_MAX checkit(buf); @@ -101,5 +107,9 @@ int main() strcpy(buf, "-18446744073709551616"); // -UINT64_MAX checkit(buf); + // Ensure we can still parse valid numbers after parsing out of range ones. + strcpy(buf, "123"); + checkit(buf); + return 0; } diff --git a/tests/test_parse_int64.expected b/tests/test_parse_int64.expected index 23a9803ebe..d9cdf5acee 100644 --- a/tests/test_parse_int64.expected +++ b/tests/test_parse_int64.expected @@ -17,10 +17,13 @@ buf=-2147483647 parseit=0, value=-2147483647 buf=-2147483648 parseit=0, value=-2147483648 buf=-2147483649 parseit=0, value=-2147483649 buf=-21474836480 parseit=0, value=-21474836480 +buf=9223372036854775806 parseit=0, value=9223372036854775806 buf=9223372036854775807 parseit=0, value=9223372036854775807 buf=9223372036854775808 parseit=0, value=9223372036854775807 buf=-9223372036854775808 parseit=0, value=-9223372036854775808 buf=-9223372036854775809 parseit=0, value=-9223372036854775808 +buf=18446744073709551614 parseit=0, value=9223372036854775807 buf=18446744073709551615 parseit=0, value=9223372036854775807 buf=18446744073709551616 parseit=0, value=9223372036854775807 buf=-18446744073709551616 parseit=0, value=-9223372036854775808 +buf=123 parseit=0, value=123 diff --git a/tests/test_printbuf.c b/tests/test_printbuf.c index 3676b54780..ee3f80dbfb 100644 --- a/tests/test_printbuf.c +++ b/tests/test_printbuf.c @@ -124,7 +124,7 @@ static void test_sprintbuf(int before_resize) memset(data, 'X', before_resize + 1 + 1); data[before_resize + 1] = '\0'; sprintbuf(pb, "%s", data); - printf("sprintbuf to just after resize(%d+1): %d, [%s], strlen(buf)=%d\n", before_resize, printbuf_length(pb), pb->buf, strlen(pb->buf)); + printf("sprintbuf to just after resize(%d+1): %d, [%s], strlen(buf)=%d\n", before_resize, printbuf_length(pb), pb->buf, (int)strlen(pb->buf)); printbuf_reset(pb); sprintbuf(pb, "plain");