diff options
author | Eric Haszlakiewicz <erh+git@nimenees.com> | 2021-07-25 19:07:06 +0000 |
---|---|---|
committer | Eric Haszlakiewicz <erh+git@nimenees.com> | 2021-07-25 19:07:06 +0000 |
commit | 6a0df2609e58f25d25bc4cfc67250fdb5d651643 (patch) | |
tree | 727a6ba15d926735ad022139aceb95f7b33571e3 | |
parent | 8c7849e6e3b985825be770041af2b948fa6d8918 (diff) | |
parent | 8c727e5ce13b288d982471120b19c037a1cb9624 (diff) | |
download | json-c-6a0df2609e58f25d25bc4cfc67250fdb5d651643.tar.gz |
Merge some old work to include (some of) PR #464 into the current master branch.
-rw-r--r-- | .clang-format | 2 | ||||
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | CMakeLists.txt | 48 | ||||
-rw-r--r-- | RELEASE_CHECKLIST.txt | 2 | ||||
-rw-r--r-- | apps/json_parse.c | 3 | ||||
-rw-r--r-- | arraylist.c | 4 | ||||
-rw-r--r-- | arraylist.h | 4 | ||||
-rwxr-xr-x | cmake-configure | 4 | ||||
-rw-r--r-- | cmake/config.h.in | 6 | ||||
-rw-r--r-- | debug.h | 6 | ||||
-rw-r--r-- | json.h.cmakein (renamed from json.h) | 2 | ||||
-rw-r--r-- | json_c_version.h | 2 | ||||
-rw-r--r-- | json_object.c | 27 | ||||
-rw-r--r-- | json_object.h | 9 | ||||
-rw-r--r-- | json_tokener.c | 6 | ||||
-rw-r--r-- | json_types.h | 2 | ||||
-rw-r--r-- | linkhash.h | 4 | ||||
-rw-r--r-- | printbuf.h | 6 | ||||
-rw-r--r-- | random_seed.c | 106 | ||||
-rw-r--r-- | strerror_override.c | 3 | ||||
-rw-r--r-- | tests/CMakeLists.txt | 54 | ||||
-rw-r--r-- | tests/test1.c | 24 | ||||
-rw-r--r-- | tests/test_cast.c | 10 | ||||
-rw-r--r-- | tests/test_cast.expected | 35 | ||||
-rw-r--r-- | tests/test_strerror.c | 11 | ||||
-rw-r--r-- | tests/test_strerror.expected | 2 | ||||
l--------- | tests/test_strerror.test | 1 |
27 files changed, 274 insertions, 110 deletions
diff --git a/.clang-format b/.clang-format index d6972be..365efb2 100644 --- a/.clang-format +++ b/.clang-format @@ -23,6 +23,8 @@ AllowShortFunctionsOnASingleLine: Empty BreakBeforeBraces: Custom # Control of individual brace wrapping cases. BraceWrapping: + # Wrap brackets inside of a case + AfterCaseLabel: true # Wrap class definition. AfterClass: true # Wrap control statements @@ -70,6 +70,7 @@ # It's not good practice to build directly in the source tree # but ignore cmake auto-generated files anyway: /json_config.h +/json.h /config.h /json-c.pc /Makefile diff --git a/CMakeLists.txt b/CMakeLists.txt index 2333d08..ed7bc03 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,6 +79,10 @@ include(CMakePackageConfigHelpers) option(BUILD_SHARED_LIBS "Default to building shared libraries" ON) option(BUILD_STATIC_LIBS "Default to building static libraries" ON) +if (BUILD_SHARED_LIBS) + add_definitions(-D JSON_C_DLL) +endif() + # Generate a release merge and test it to verify the correctness of republishing the package. ADD_CUSTOM_TARGET(distcheck COMMAND make package_source @@ -97,6 +101,8 @@ option(DISABLE_WERROR "Avoid treating compiler warnings as fatal option(ENABLE_RDRAND "Enable RDRAND Hardware RNG Hash Seed." OFF) option(ENABLE_THREADING "Enable partial threading support." OFF) option(OVERRIDE_GET_RANDOM_SEED "Override json_c_get_random_seed() with custom code." OFF) +option(DISABLE_EXTRA_LIBS "Avoid linking against extra libraries, such as libbsd." OFF) +option(DISABLE_JSON_POINTER "Disable JSON pointer (RFC6901) support." OFF) if (UNIX OR MINGW OR CYGWIN) @@ -148,7 +154,10 @@ check_include_file(sys/random.h HAVE_SYS_RANDOM_H) check_include_file(sys/stat.h HAVE_SYS_STAT_H) check_include_file(xlocale.h HAVE_XLOCALE_H) -if (HAVE_INTTYPES_H AND NOT MSVC) +if (HAVE_INTTYPES_H) + # Set a json-c specific var to stamp into json_config.h + # in a way that hopefull ywon't conflict with other + # projects that use json-c. set(JSON_C_HAVE_INTTYPES_H 1) endif() @@ -170,6 +179,17 @@ check_symbol_exists(vasprintf "stdio.h" HAVE_VASPRINTF) check_symbol_exists(vsnprintf "stdio.h" HAVE_VSNPRINTF) check_symbol_exists(vprintf "stdio.h" HAVE_VPRINTF) +check_symbol_exists(arc4random "stdlib.h" HAVE_ARC4RANDOM) +if (NOT HAVE_ARC4RANDOM AND DISABLE_EXTRA_LIBS STREQUAL "OFF") + check_include_file(bsd/stdlib.h HAVE_BSD_STDLIB_H) + if (HAVE_BSD_STDLIB_H) + list(APPEND CMAKE_REQUIRED_LIBRARIES "-lbsd") + link_libraries(bsd) + unset(HAVE_ARC4RANDOM CACHE) + check_symbol_exists(arc4random "bsd/stdlib.h" HAVE_ARC4RANDOM) + endif() +endif() + if (HAVE_FCNTL_H) check_symbol_exists(open "fcntl.h" HAVE_OPEN) endif() @@ -269,7 +289,7 @@ message(STATUS "Wrote ${PROJECT_BINARY_DIR}/config.h") configure_file(${PROJECT_SOURCE_DIR}/cmake/json_config.h.in ${PROJECT_BINARY_DIR}/json_config.h) message(STATUS "Wrote ${PROJECT_BINARY_DIR}/json_config.h") -if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") +if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections") if ("${DISABLE_WERROR}" STREQUAL "OFF") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") @@ -358,14 +378,13 @@ set(JSON_C_PUBLIC_HEADERS # Note: config.h is _not_ included here ${PROJECT_BINARY_DIR}/json_config.h - ${PROJECT_SOURCE_DIR}/json.h + ${PROJECT_BINARY_DIR}/json.h ${PROJECT_SOURCE_DIR}/arraylist.h ${PROJECT_SOURCE_DIR}/debug.h ${PROJECT_SOURCE_DIR}/json_c_version.h ${PROJECT_SOURCE_DIR}/json_inttypes.h ${PROJECT_SOURCE_DIR}/json_object.h ${PROJECT_SOURCE_DIR}/json_object_iterator.h - ${PROJECT_SOURCE_DIR}/json_pointer.h ${PROJECT_SOURCE_DIR}/json_tokener.h ${PROJECT_SOURCE_DIR}/json_types.h ${PROJECT_SOURCE_DIR}/json_util.h @@ -392,7 +411,6 @@ set(JSON_C_SOURCES ${PROJECT_SOURCE_DIR}/json_c_version.c ${PROJECT_SOURCE_DIR}/json_object.c ${PROJECT_SOURCE_DIR}/json_object_iterator.c - ${PROJECT_SOURCE_DIR}/json_pointer.c ${PROJECT_SOURCE_DIR}/json_tokener.c ${PROJECT_SOURCE_DIR}/json_util.c ${PROJECT_SOURCE_DIR}/json_visit.c @@ -402,16 +420,28 @@ set(JSON_C_SOURCES ${PROJECT_SOURCE_DIR}/strerror_override.c ) +if (NOT DISABLE_JSON_POINTER) + set(JSON_C_PUBLIC_HEADERS ${JSON_C_PUBLIC_HEADERS} ${PROJECT_SOURCE_DIR}/json_pointer.h) + set(JSON_C_SOURCES ${JSON_C_SOURCES} ${PROJECT_SOURCE_DIR}/json_pointer.c) + set(JSON_H_JSON_POINTER "#include \"json_pointer.h\"") +else() + set(JSON_H_JSON_POINTER "") +endif() + +configure_file(json.h.cmakein ${PROJECT_BINARY_DIR}/json.h @ONLY) + include_directories(${PROJECT_SOURCE_DIR}) include_directories(${PROJECT_BINARY_DIR}) add_subdirectory(doc) # uninstall -add_custom_target(uninstall - COMMAND cat ${PROJECT_BINARY_DIR}/install_manifest.txt | xargs rm - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} -) +if(NOT TARGET uninstall) + add_custom_target(uninstall + COMMAND cat ${PROJECT_BINARY_DIR}/install_manifest.txt | xargs rm + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + ) +endif() # XXX for a normal full distribution we'll need to figure out # XXX how to build both shared and static libraries. diff --git a/RELEASE_CHECKLIST.txt b/RELEASE_CHECKLIST.txt index 8e70617..9f6b6db 100644 --- a/RELEASE_CHECKLIST.txt +++ b/RELEASE_CHECKLIST.txt @@ -93,7 +93,7 @@ Create the release tarballs: echo .git > excludes tar -czf json-c-${release}.tar.gz -X excludes json-c-${release} - echo doc >> excludes + echo 'doc/*' >> excludes tar -czf json-c-${release}-nodoc.tar.gz -X excludes json-c-${release} ------------ diff --git a/apps/json_parse.c b/apps/json_parse.c index bba4622..72b31a8 100644 --- a/apps/json_parse.c +++ b/apps/json_parse.c @@ -82,7 +82,8 @@ static int parseit(int fd, int (*callback)(struct json_object *)) int parse_end = json_tokener_get_parse_end(tok); if (obj == NULL && jerr != json_tokener_continue) { - char *aterr = &buf[start_pos + parse_end]; + char *aterr = (start_pos + parse_end < sizeof(buf)) ? + &buf[start_pos + parse_end] : ""; fflush(stdout); int fail_offset = total_read - ret + start_pos + parse_end; fprintf(stderr, "Failed at offset %d: %s %c\n", fail_offset, diff --git a/arraylist.c b/arraylist.c index c21b8e1..d8e12d1 100644 --- a/arraylist.c +++ b/arraylist.c @@ -45,6 +45,8 @@ struct array_list *array_list_new2(array_list_free_fn *free_fn, int initial_size { struct array_list *arr; + if (initial_size < 0 || (size_t)initial_size >= SIZE_T_MAX / sizeof(void *)) + return NULL; arr = (struct array_list *)malloc(sizeof(struct array_list)); if (!arr) return NULL; @@ -106,6 +108,8 @@ int array_list_shrink(struct array_list *arr, size_t empty_slots) void *t; size_t new_size; + if (empty_slots >= SIZE_T_MAX / sizeof(void *) - arr->length) + return -1; new_size = arr->length + empty_slots; if (new_size == arr->size) return 0; diff --git a/arraylist.h b/arraylist.h index 1b18756..f541706 100644 --- a/arraylist.h +++ b/arraylist.h @@ -15,8 +15,8 @@ * Although this is exposed by the json_object_get_array() method, * it is not recommended for direct use. */ -#ifndef _arraylist_h_ -#define _arraylist_h_ +#ifndef _json_c_arraylist_h_ +#define _json_c_arraylist_h_ #ifdef __cplusplus extern "C" { diff --git a/cmake-configure b/cmake-configure index c8e44ae..dc695e5 100755 --- a/cmake-configure +++ b/cmake-configure @@ -30,6 +30,7 @@ $0 [<configure_options>] [-- [<cmake options>]] --enable-static build static libraries [default=yes] --disable-Bsymbolic Avoid linking with -Bsymbolic-function --disable-werror Avoid treating compiler warnings as fatal errors + --disable-extra-libs Avoid linking against extra libraries, such as libbsd EOF exit @@ -73,6 +74,9 @@ while [ $# -gt 0 ] ; do --disable-werror) FLAGS+=(-DDISABLE_WERROR=ON) ;; + --disable-extra-libs) + FLAGS+=(-DDISABLE_EXTRA_LIBS=ON) + ;; --) shift break diff --git a/cmake/config.h.in b/cmake/config.h.in index 9e097cb..be0202a 100644 --- a/cmake/config.h.in +++ b/cmake/config.h.in @@ -74,6 +74,12 @@ /* Define to 1 if you have the <xlocale.h> header file. */ #cmakedefine HAVE_XLOCALE_H +/* Define to 1 if you have the <bsd/stdlib.h> header file. */ +#cmakedefine HAVE_BSD_STDLIB_H + +/* Define to 1 if you have `arc4random' */ +#cmakedefine HAVE_ARC4RANDOM + /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ #cmakedefine HAVE_DOPRNT @@ -14,8 +14,8 @@ * @file * @brief Do not use, json-c internal, may be changed or removed at any time. */ -#ifndef _DEBUG_H_ -#define _DEBUG_H_ +#ifndef _JSON_C_DEBUG_H_ +#define _JSON_C_DEBUG_H_ #include <stdlib.h> @@ -24,7 +24,7 @@ extern "C" { #endif #ifndef JSON_EXPORT -#if defined(_MSC_VER) +#if defined(_MSC_VER) && defined(JSON_C_DLL) #define JSON_EXPORT __declspec(dllexport) #else #define JSON_EXPORT extern @@ -26,7 +26,7 @@ extern "C" { #include "json_c_version.h" #include "json_object.h" #include "json_object_iterator.h" -#include "json_pointer.h" +@JSON_H_JSON_POINTER@ #include "json_tokener.h" #include "json_util.h" #include "linkhash.h" diff --git a/json_c_version.h b/json_c_version.h index 00de4b3..d15ad64 100644 --- a/json_c_version.h +++ b/json_c_version.h @@ -24,7 +24,7 @@ extern "C" { #define JSON_C_VERSION "0.15.99" #ifndef JSON_EXPORT -#if defined(_MSC_VER) +#if defined(_MSC_VER) && defined(JSON_C_DLL) #define JSON_EXPORT __declspec(dllexport) #else #define JSON_EXPORT extern diff --git a/json_object.c b/json_object.c index a555da5..9df5809 100644 --- a/json_object.c +++ b/json_object.c @@ -216,7 +216,7 @@ static inline const char *get_string_component(const struct json_object *jso) static int json_escape_str(struct printbuf *pb, const char *str, size_t len, int flags) { - int pos = 0, start_offset = 0; + size_t pos = 0, start_offset = 0; unsigned char c; while (len--) { @@ -237,7 +237,7 @@ static int json_escape_str(struct printbuf *pb, const char *str, size_t len, int break; } - if (pos - start_offset > 0) + if (pos > start_offset) printbuf_memappend(pb, str + start_offset, pos - start_offset); if (c == '\b') @@ -263,7 +263,7 @@ static int json_escape_str(struct printbuf *pb, const char *str, size_t len, int if (c < ' ') { char sbuf[7]; - if (pos - start_offset > 0) + if (pos > start_offset) printbuf_memappend(pb, str + start_offset, pos - start_offset); snprintf(sbuf, sizeof(sbuf), "\\u00%c%c", json_hex_chars[c >> 4], @@ -275,7 +275,7 @@ static int json_escape_str(struct printbuf *pb, const char *str, size_t len, int pos++; } } - if (pos - start_offset > 0) + if (pos > start_offset) printbuf_memappend(pb, str + start_offset, pos - start_offset); return 0; } @@ -1256,17 +1256,17 @@ static struct json_object *_json_object_new_string(const char *s, const size_t l struct json_object_string *jso; /* - * Structures Actual memory layout - * ------------------- -------------------- + * Structures Actual memory layout + * ------------------- -------------------- * [json_object_string [json_object_string * [json_object] [json_object] - * ...other fields... ...other fields... + * ...other fields... ...other fields... * c_string] len - * bytes + * bytes * of * string * data - * \0] + * \0] */ if (len > (SSIZE_T_MAX - (sizeof(*jso) - sizeof(jso->c_string)) - 1)) return NULL; @@ -1333,9 +1333,10 @@ static int _json_object_set_string_len(json_object *jso, const char *s, size_t l if (jso == NULL || jso->o_type != json_type_string) return 0; - if (len >= SSIZE_T_MAX - 1) + if (len >= INT_MAX - 1) // jso->len is a signed ssize_t, so it can't hold the - // full size_t range. + // full size_t range. json_object_get_string_len returns + // length as int, cap length at INT_MAX. return 0; dstbuf = get_string_component_mutable(jso); @@ -1732,7 +1733,7 @@ static int json_object_deep_copy_recursive(struct json_object *src, struct json_ /* This handles the `json_type_null` case */ if (!iter.val) jso = NULL; - else if (json_object_deep_copy_recursive(iter.val, src, iter.key, -1, &jso, + else if (json_object_deep_copy_recursive(iter.val, src, iter.key, UINT_MAX, &jso, shallow_copy) < 0) { json_object_put(jso); @@ -1797,7 +1798,7 @@ int json_object_deep_copy(struct json_object *src, struct json_object **dst, if (shallow_copy == NULL) shallow_copy = json_c_shallow_copy_default; - rc = json_object_deep_copy_recursive(src, NULL, NULL, -1, dst, shallow_copy); + rc = json_object_deep_copy_recursive(src, NULL, NULL, UINT_MAX, dst, shallow_copy); if (rc < 0) { json_object_put(*dst); diff --git a/json_object.h b/json_object.h index a54541c..d67f384 100644 --- a/json_object.h +++ b/json_object.h @@ -470,7 +470,7 @@ JSON_EXPORT void json_object_object_del(struct json_object *obj, const char *key * @param val the local name for the json_object* object variable defined in * the body */ -#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && __STDC_VERSION__ >= 199901L +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) #define json_object_object_foreach(obj, key, val) \ char *key = NULL; \ @@ -502,7 +502,7 @@ JSON_EXPORT void json_object_object_del(struct json_object *obj, const char *key : 0); \ entry##key = entry_next##key) -#endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) && __STDC_VERSION__ >= 199901L */ +#endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) && (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) */ /** Iterate through all keys and values of an object (ANSI C Safe) * @param obj the json_object instance @@ -656,8 +656,9 @@ JSON_EXPORT struct json_object *json_object_new_boolean(json_bool b); * The type is coerced to a json_bool if the passed object is not a json_bool. * integer and double objects will return 0 if there value is zero * or 1 otherwise. If the passed object is a string it will return - * 1 if it has a non zero length. If any other object type is passed - * 1 will be returned if the object is not NULL. + * 1 if it has a non zero length. + * If any other object type is passed 0 will be returned, even non-empty + * json_type_array and json_type_object objects. * * @param obj the json_object instance * @returns a json_bool diff --git a/json_tokener.c b/json_tokener.c index e16db6b..1a74155 100644 --- a/json_tokener.c +++ b/json_tokener.c @@ -155,6 +155,12 @@ struct json_tokener *json_tokener_new_ex(int depth) return NULL; } tok->pb = printbuf_new(); + if (!tok->pb) + { + free(tok); + free(tok->stack); + return NULL; + } tok->max_depth = depth; json_tokener_reset(tok); return tok; diff --git a/json_types.h b/json_types.h index 67f4497..b7e55ad 100644 --- a/json_types.h +++ b/json_types.h @@ -18,7 +18,7 @@ extern "C" { #endif #ifndef JSON_EXPORT -#if defined(_MSC_VER) +#if defined(_MSC_VER) && defined(JSON_C_DLL) #define JSON_EXPORT __declspec(dllexport) #else #define JSON_EXPORT extern @@ -16,8 +16,8 @@ * this is exposed by the json_object_get_object() function and within the * json_object_iter type, it is not recommended for direct use. */ -#ifndef _linkhash_h_ -#define _linkhash_h_ +#ifndef _json_c_linkhash_h_ +#define _json_c_linkhash_h_ #include "json_object.h" @@ -20,11 +20,11 @@ * json_object_set_serializer() direct use of this is not * recommended. */ -#ifndef _printbuf_h_ -#define _printbuf_h_ +#ifndef _json_c_printbuf_h_ +#define _json_c_printbuf_h_ #ifndef JSON_EXPORT -#if defined(_MSC_VER) +#if defined(_MSC_VER) && defined(JSON_C_DLL) #define JSON_EXPORT __declspec(dllexport) #else #define JSON_EXPORT extern diff --git a/random_seed.c b/random_seed.c index 17727c6..f474e39 100644 --- a/random_seed.c +++ b/random_seed.c @@ -13,9 +13,23 @@ #include "config.h" #include "strerror_override.h" #include <stdio.h> +#include <stdlib.h> +#ifdef HAVE_BSD_STDLIB_H +#include <bsd/stdlib.h> +#endif #define DEBUG_SEED(s) +#if defined(__APPLE__) || defined(__unix__) || defined(__linux__) +#define HAVE_DEV_RANDOM 1 +#endif + +#ifdef HAVE_ARC4RANDOM +#undef HAVE_GETRANDOM +#undef HAVE_DEV_RANDOM +#undef HAVE_CRYPTGENRANDOM +#endif + #if defined ENABLE_RDRAND /* cpuid */ @@ -162,36 +176,38 @@ retry: #include <sys/random.h> #endif -static int get_getrandom_seed(void) +static int get_getrandom_seed(int *seed) { - DEBUG_SEED("get_dev_random_seed"); + DEBUG_SEED("get_getrandom_seed"); - int r; ssize_t ret; - do { - ret = getrandom(&r, sizeof(r), 0); + do + { + ret = getrandom(seed, sizeof(*seed), GRND_NONBLOCK); } while ((ret == -1) && (errno == EINTR)); if (ret == -1) { if (errno == ENOSYS) /* syscall not available in kernel */ return -1; + if (errno == EAGAIN) /* entropy not yet initialized */ + return -1; fprintf(stderr, "error from getrandom(): %s", strerror(errno)); - exit(1); + return -1; } - if (ret != sizeof(r)) + if (ret != sizeof(*seed)) return -1; - return r; + return 0; } #endif /* defined HAVE_GETRANDOM */ -/* has_dev_urandom */ +/* get_dev_random_seed */ -#if defined(__APPLE__) || defined(__unix__) || defined(__linux__) +#ifdef HAVE_DEV_RANDOM #include <fcntl.h> #include <string.h> @@ -201,43 +217,34 @@ static int get_getrandom_seed(void) #include <stdlib.h> #include <sys/stat.h> -#define HAVE_DEV_RANDOM 1 - static const char *dev_random_file = "/dev/urandom"; -static int has_dev_urandom(void) +static int get_dev_random_seed(int *seed) { + DEBUG_SEED("get_dev_random_seed"); + struct stat buf; if (stat(dev_random_file, &buf)) - { - return 0; - } - return ((buf.st_mode & S_IFCHR) != 0); -} - -/* get_dev_random_seed */ - -static int get_dev_random_seed(void) -{ - DEBUG_SEED("get_dev_random_seed"); + return -1; + if ((buf.st_mode & S_IFCHR) == 0) + return -1; int fd = open(dev_random_file, O_RDONLY); if (fd < 0) { fprintf(stderr, "error opening %s: %s", dev_random_file, strerror(errno)); - exit(1); + return -1; } - int r; - ssize_t nread = read(fd, &r, sizeof(r)); - if (nread != sizeof(r)) + ssize_t nread = read(fd, seed, sizeof(*seed)); + if (nread != sizeof(*seed)) { fprintf(stderr, "error short read %s: %s", dev_random_file, strerror(errno)); - exit(1); + return -1; } close(fd); - return r; + return 0; } #endif @@ -260,13 +267,10 @@ static int get_dev_random_seed(void) #pragma comment(lib, "advapi32.lib") #endif -static int get_time_seed(void); - -static int get_cryptgenrandom_seed(void) +static int get_cryptgenrandom_seed(int *seed) { HCRYPTPROV hProvider = 0; DWORD dwFlags = CRYPT_VERIFYCONTEXT; - int r; DEBUG_SEED("get_cryptgenrandom_seed"); @@ -277,34 +281,36 @@ static int get_cryptgenrandom_seed(void) if (!CryptAcquireContextA(&hProvider, 0, 0, PROV_RSA_FULL, dwFlags)) { fprintf(stderr, "error CryptAcquireContextA 0x%08lx", GetLastError()); - r = get_time_seed(); + return -1; } else { - BOOL ret = CryptGenRandom(hProvider, sizeof(r), (BYTE*)&r); + BOOL ret = CryptGenRandom(hProvider, sizeof(*seed), (BYTE *)seed); CryptReleaseContext(hProvider, 0); if (!ret) { fprintf(stderr, "error CryptGenRandom 0x%08lx", GetLastError()); - r = get_time_seed(); + return -1; } } - return r; + return 0; } #endif /* get_time_seed */ +#ifndef HAVE_ARC4RANDOM #include <time.h> static int get_time_seed(void) { DEBUG_SEED("get_time_seed"); - return (int)time(NULL) * 433494437; + return (unsigned)time(NULL) * 433494437; } +#endif /* json_c_get_random_seed */ @@ -317,19 +323,31 @@ int json_c_get_random_seed(void) if (has_rdrand()) return get_rdrand_seed(); #endif +#ifdef HAVE_ARC4RANDOM + /* arc4random never fails, so use it if it's available */ + return arc4random(); +#else #ifdef HAVE_GETRANDOM { - int seed = get_getrandom_seed(); - if (seed != -1) + int seed; + if (get_getrandom_seed(&seed) == 0) return seed; } #endif #if defined HAVE_DEV_RANDOM && HAVE_DEV_RANDOM - if (has_dev_urandom()) - return get_dev_random_seed(); + { + int seed; + if (get_dev_random_seed(&seed) == 0) + return seed; + } #endif #if defined HAVE_CRYPTGENRANDOM && HAVE_CRYPTGENRANDOM - return get_cryptgenrandom_seed(); + { + int seed; + if (get_cryptgenrandom_seed(&seed) == 0) + return seed; + } #endif return get_time_seed(); +#endif /* !HAVE_ARC4RANDOM */ } diff --git a/strerror_override.c b/strerror_override.c index 7a262f7..a3dd377 100644 --- a/strerror_override.c +++ b/strerror_override.c @@ -94,7 +94,7 @@ char *_json_c_strerror(int errno_in) } // It's not one of the known errno values, return the numeric value. - for (ii = 0; errno_in > 10; errno_in /= 10, ii++) + for (ii = 0; errno_in >= 10; errno_in /= 10, ii++) { digbuf[ii] = "0123456789"[(errno_in % 10)]; } @@ -105,5 +105,6 @@ char *_json_c_strerror(int errno_in) { errno_buf[start_idx] = digbuf[ii]; } + errno_buf[start_idx] = '\0'; return errno_buf; } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 125f615..d7abf51 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -12,32 +12,38 @@ target_link_libraries(test2Formatted PRIVATE ${PROJECT_NAME}) include_directories(PUBLIC ${CMAKE_SOURCE_DIR}) -foreach(TESTNAME - test1 - test2 - test4 - testReplaceExisting - test_cast - test_charcase - test_compare - test_deep_copy - test_double_serializer - test_float - test_int_add - test_json_pointer - test_locale - test_null - test_parse - test_parse_int64 - test_printbuf - test_set_serializer - test_set_value - test_util_file - test_visit - test_object_iterator) +set(ALL_TEST_NAMES + test1 + test2 + test4 + testReplaceExisting + test_cast + test_charcase + test_compare + test_deep_copy + test_double_serializer + test_float + test_int_add + test_locale + test_null + test_parse + test_parse_int64 + test_printbuf + test_set_serializer + test_set_value + test_strerror + test_util_file + test_visit + test_object_iterator) + +if (NOT DISABLE_JSON_POINTER) + set(ALL_TEST_NAMES ${ALL_TEST_NAMES} test_json_pointer) +endif() + +foreach(TESTNAME ${ALL_TEST_NAMES}) add_executable(${TESTNAME} ${TESTNAME}.c) -if(${TESTNAME} STREQUAL test_util_file) +if(${TESTNAME} STREQUAL test_strerror OR ${TESTNAME} STREQUAL test_util_file) # For output consistency, we need _json_c_strerror() in some tests: target_sources(${TESTNAME} PRIVATE ../strerror_override.c) endif() diff --git a/tests/test1.c b/tests/test1.c index 6682120..4d29601 100644 --- a/tests/test1.c +++ b/tests/test1.c @@ -1,9 +1,12 @@ #include <assert.h> +#include <limits.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include "config.h" + #include "json.h" #include "parse_flags.h" @@ -307,6 +310,27 @@ int main(int argc, char **argv) } printf("my_object.to_string()=%s\n", json_object_to_json_string(my_object)); + json_object_put(my_array); + my_array = json_object_new_array_ext(INT_MIN + 1); + if (my_array != NULL) + { + printf("ERROR: able to allocate an array of negative size!\n"); + fflush(stdout); + json_object_put(my_array); + my_array = NULL; + } + +#if SIZEOF_SIZE_T == SIZEOF_INT + my_array = json_object_new_array_ext(INT_MAX / 2 + 2); + if (my_array != NULL) + { + printf("ERROR: able to allocate an array of insufficient size!\n"); + fflush(stdout); + json_object_put(my_array); + my_array = NULL; + } +#endif + json_object_put(my_string); json_object_put(my_int); json_object_put(my_null); diff --git a/tests/test_cast.c b/tests/test_cast.c index fb63e0d..fc769f5 100644 --- a/tests/test_cast.c +++ b/tests/test_cast.c @@ -28,6 +28,11 @@ int main(int argc, char **argv) \"int64_number\": 2147483649,\n\ \"negative_number\": -321321321,\n\ \"a_null\": null,\n\ + \"empty_array\": [],\n\ + \"nonempty_array\": [ 123 ],\n\ + \"array_with_zero\": [ 0 ],\n\ + \"empty_object\": {},\n\ + \"nonempty_object\": { \"a\": 123 },\n\ }"; /* Note: 2147483649 = INT_MAX + 2 */ /* Note: 9223372036854775809 = INT64_MAX + 2 */ @@ -49,6 +54,11 @@ int main(int argc, char **argv) getit(new_obj, "int64_number"); getit(new_obj, "negative_number"); getit(new_obj, "a_null"); + getit(new_obj, "empty_array"); + getit(new_obj, "nonempty_array"); + getit(new_obj, "array_with_zero"); + getit(new_obj, "empty_object"); + getit(new_obj, "nonempty_object"); // Now check the behaviour of the json_object_is_type() function. printf("\n================================\n"); diff --git a/tests/test_cast.expected b/tests/test_cast.expected index 347d540..6a19de9 100644 --- a/tests/test_cast.expected +++ b/tests/test_cast.expected @@ -7,6 +7,11 @@ Parsed input: { "int64_number": 2147483649, "negative_number": -321321321, "a_null": null, + "empty_array": [], + "nonempty_array": [ 123 ], + "array_with_zero": [ 0 ], + "empty_object": {}, + "nonempty_object": { "a": 123 }, } Result is not NULL new_obj.string_of_digits json_object_get_type()=string @@ -57,6 +62,36 @@ new_obj.a_null json_object_get_int64()=0 new_obj.a_null json_object_get_uint64()=0 new_obj.a_null json_object_get_boolean()=0 new_obj.a_null json_object_get_double()=0.000000 +new_obj.empty_array json_object_get_type()=array +new_obj.empty_array json_object_get_int()=0 +new_obj.empty_array json_object_get_int64()=0 +new_obj.empty_array json_object_get_uint64()=0 +new_obj.empty_array json_object_get_boolean()=0 +new_obj.empty_array json_object_get_double()=0.000000 +new_obj.nonempty_array json_object_get_type()=array +new_obj.nonempty_array json_object_get_int()=0 +new_obj.nonempty_array json_object_get_int64()=0 +new_obj.nonempty_array json_object_get_uint64()=0 +new_obj.nonempty_array json_object_get_boolean()=0 +new_obj.nonempty_array json_object_get_double()=0.000000 +new_obj.array_with_zero json_object_get_type()=array +new_obj.array_with_zero json_object_get_int()=0 +new_obj.array_with_zero json_object_get_int64()=0 +new_obj.array_with_zero json_object_get_uint64()=0 +new_obj.array_with_zero json_object_get_boolean()=0 +new_obj.array_with_zero json_object_get_double()=0.000000 +new_obj.empty_object json_object_get_type()=object +new_obj.empty_object json_object_get_int()=0 +new_obj.empty_object json_object_get_int64()=0 +new_obj.empty_object json_object_get_uint64()=0 +new_obj.empty_object json_object_get_boolean()=0 +new_obj.empty_object json_object_get_double()=0.000000 +new_obj.nonempty_object json_object_get_type()=object +new_obj.nonempty_object json_object_get_int()=0 +new_obj.nonempty_object json_object_get_int64()=0 +new_obj.nonempty_object json_object_get_uint64()=0 +new_obj.nonempty_object json_object_get_boolean()=0 +new_obj.nonempty_object json_object_get_double()=0.000000 ================================ json_object_is_type: null,boolean,double,int,object,array,string diff --git a/tests/test_strerror.c b/tests/test_strerror.c new file mode 100644 index 0000000..1780564 --- /dev/null +++ b/tests/test_strerror.c @@ -0,0 +1,11 @@ +#include "strerror_override.h" +#include "strerror_override_private.h" + +#include <stdio.h> + +int main(int argc, char **argv) +{ + puts(strerror(10000)); + puts(strerror(999)); + return 0; +} diff --git a/tests/test_strerror.expected b/tests/test_strerror.expected new file mode 100644 index 0000000..b6b3bb6 --- /dev/null +++ b/tests/test_strerror.expected @@ -0,0 +1,2 @@ +ERRNO=10000 +ERRNO=999 diff --git a/tests/test_strerror.test b/tests/test_strerror.test new file mode 120000 index 0000000..58a13f4 --- /dev/null +++ b/tests/test_strerror.test @@ -0,0 +1 @@ +test_basic.test
\ No newline at end of file |