Browse Source

Merge some old work to include (some of) PR #464 into the current master branch.

tags/json-c-0.16-20220414
Eric Haszlakiewicz 4 years ago
parent
commit
6a0df2609e
27 changed files with 274 additions and 110 deletions
  1. +2
    -0
      .clang-format
  2. +1
    -0
      .gitignore
  3. +39
    -9
      CMakeLists.txt
  4. +1
    -1
      RELEASE_CHECKLIST.txt
  5. +2
    -1
      apps/json_parse.c
  6. +4
    -0
      arraylist.c
  7. +2
    -2
      arraylist.h
  8. +4
    -0
      cmake-configure
  9. +6
    -0
      cmake/config.h.in
  10. +3
    -3
      debug.h
  11. +1
    -1
      json.h.cmakein
  12. +1
    -1
      json_c_version.h
  13. +14
    -13
      json_object.c
  14. +5
    -4
      json_object.h
  15. +6
    -0
      json_tokener.c
  16. +1
    -1
      json_types.h
  17. +2
    -2
      linkhash.h
  18. +3
    -3
      printbuf.h
  19. +62
    -44
      random_seed.c
  20. +2
    -1
      strerror_override.c
  21. +30
    -24
      tests/CMakeLists.txt
  22. +24
    -0
      tests/test1.c
  23. +10
    -0
      tests/test_cast.c
  24. +35
    -0
      tests/test_cast.expected
  25. +11
    -0
      tests/test_strerror.c
  26. +2
    -0
      tests/test_strerror.expected
  27. +1
    -0
      tests/test_strerror.test

+ 2
- 0
.clang-format View File

@@ -23,6 +23,8 @@ AllowShortFunctionsOnASingleLine: Empty
BreakBeforeBraces: Custom BreakBeforeBraces: Custom
# Control of individual brace wrapping cases. # Control of individual brace wrapping cases.
BraceWrapping: BraceWrapping:
# Wrap brackets inside of a case
AfterCaseLabel: true
# Wrap class definition. # Wrap class definition.
AfterClass: true AfterClass: true
# Wrap control statements # Wrap control statements


+ 1
- 0
.gitignore View File

@@ -70,6 +70,7 @@
# It's not good practice to build directly in the source tree # It's not good practice to build directly in the source tree
# but ignore cmake auto-generated files anyway: # but ignore cmake auto-generated files anyway:
/json_config.h /json_config.h
/json.h
/config.h /config.h
/json-c.pc /json-c.pc
/Makefile /Makefile


+ 39
- 9
CMakeLists.txt View File

@@ -79,6 +79,10 @@ include(CMakePackageConfigHelpers)
option(BUILD_SHARED_LIBS "Default to building shared libraries" ON) option(BUILD_SHARED_LIBS "Default to building shared libraries" ON)
option(BUILD_STATIC_LIBS "Default to building static 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. # Generate a release merge and test it to verify the correctness of republishing the package.
ADD_CUSTOM_TARGET(distcheck ADD_CUSTOM_TARGET(distcheck
COMMAND make package_source 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_RDRAND "Enable RDRAND Hardware RNG Hash Seed." OFF)
option(ENABLE_THREADING "Enable partial threading support." 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(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) 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(sys/stat.h HAVE_SYS_STAT_H)
check_include_file(xlocale.h HAVE_XLOCALE_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) set(JSON_C_HAVE_INTTYPES_H 1)
endif() endif()


@@ -170,6 +179,17 @@ check_symbol_exists(vasprintf "stdio.h" HAVE_VASPRINTF)
check_symbol_exists(vsnprintf "stdio.h" HAVE_VSNPRINTF) check_symbol_exists(vsnprintf "stdio.h" HAVE_VSNPRINTF)
check_symbol_exists(vprintf "stdio.h" HAVE_VPRINTF) 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) if (HAVE_FCNTL_H)
check_symbol_exists(open "fcntl.h" HAVE_OPEN) check_symbol_exists(open "fcntl.h" HAVE_OPEN)
endif() 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) 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") 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") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections")
if ("${DISABLE_WERROR}" STREQUAL "OFF") if ("${DISABLE_WERROR}" STREQUAL "OFF")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
@@ -358,14 +378,13 @@ set(JSON_C_PUBLIC_HEADERS
# Note: config.h is _not_ included here # Note: config.h is _not_ included here
${PROJECT_BINARY_DIR}/json_config.h ${PROJECT_BINARY_DIR}/json_config.h


${PROJECT_SOURCE_DIR}/json.h
${PROJECT_BINARY_DIR}/json.h
${PROJECT_SOURCE_DIR}/arraylist.h ${PROJECT_SOURCE_DIR}/arraylist.h
${PROJECT_SOURCE_DIR}/debug.h ${PROJECT_SOURCE_DIR}/debug.h
${PROJECT_SOURCE_DIR}/json_c_version.h ${PROJECT_SOURCE_DIR}/json_c_version.h
${PROJECT_SOURCE_DIR}/json_inttypes.h ${PROJECT_SOURCE_DIR}/json_inttypes.h
${PROJECT_SOURCE_DIR}/json_object.h ${PROJECT_SOURCE_DIR}/json_object.h
${PROJECT_SOURCE_DIR}/json_object_iterator.h ${PROJECT_SOURCE_DIR}/json_object_iterator.h
${PROJECT_SOURCE_DIR}/json_pointer.h
${PROJECT_SOURCE_DIR}/json_tokener.h ${PROJECT_SOURCE_DIR}/json_tokener.h
${PROJECT_SOURCE_DIR}/json_types.h ${PROJECT_SOURCE_DIR}/json_types.h
${PROJECT_SOURCE_DIR}/json_util.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_c_version.c
${PROJECT_SOURCE_DIR}/json_object.c ${PROJECT_SOURCE_DIR}/json_object.c
${PROJECT_SOURCE_DIR}/json_object_iterator.c ${PROJECT_SOURCE_DIR}/json_object_iterator.c
${PROJECT_SOURCE_DIR}/json_pointer.c
${PROJECT_SOURCE_DIR}/json_tokener.c ${PROJECT_SOURCE_DIR}/json_tokener.c
${PROJECT_SOURCE_DIR}/json_util.c ${PROJECT_SOURCE_DIR}/json_util.c
${PROJECT_SOURCE_DIR}/json_visit.c ${PROJECT_SOURCE_DIR}/json_visit.c
@@ -402,16 +420,28 @@ set(JSON_C_SOURCES
${PROJECT_SOURCE_DIR}/strerror_override.c ${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_SOURCE_DIR})
include_directories(${PROJECT_BINARY_DIR}) include_directories(${PROJECT_BINARY_DIR})


add_subdirectory(doc) add_subdirectory(doc)


# uninstall # 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 for a normal full distribution we'll need to figure out
# XXX how to build both shared and static libraries. # XXX how to build both shared and static libraries.


+ 1
- 1
RELEASE_CHECKLIST.txt View File

@@ -93,7 +93,7 @@ Create the release tarballs:
echo .git > excludes echo .git > excludes
tar -czf json-c-${release}.tar.gz -X excludes json-c-${release} 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} tar -czf json-c-${release}-nodoc.tar.gz -X excludes json-c-${release}


------------ ------------


+ 2
- 1
apps/json_parse.c View File

@@ -82,7 +82,8 @@ static int parseit(int fd, int (*callback)(struct json_object *))
int parse_end = json_tokener_get_parse_end(tok); int parse_end = json_tokener_get_parse_end(tok);
if (obj == NULL && jerr != json_tokener_continue) 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); fflush(stdout);
int fail_offset = total_read - ret + start_pos + parse_end; int fail_offset = total_read - ret + start_pos + parse_end;
fprintf(stderr, "Failed at offset %d: %s %c\n", fail_offset, fprintf(stderr, "Failed at offset %d: %s %c\n", fail_offset,


+ 4
- 0
arraylist.c View File

@@ -45,6 +45,8 @@ struct array_list *array_list_new2(array_list_free_fn *free_fn, int initial_size
{ {
struct array_list *arr; 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)); arr = (struct array_list *)malloc(sizeof(struct array_list));
if (!arr) if (!arr)
return NULL; return NULL;
@@ -106,6 +108,8 @@ int array_list_shrink(struct array_list *arr, size_t empty_slots)
void *t; void *t;
size_t new_size; size_t new_size;


if (empty_slots >= SIZE_T_MAX / sizeof(void *) - arr->length)
return -1;
new_size = arr->length + empty_slots; new_size = arr->length + empty_slots;
if (new_size == arr->size) if (new_size == arr->size)
return 0; return 0;


+ 2
- 2
arraylist.h View File

@@ -15,8 +15,8 @@
* Although this is exposed by the json_object_get_array() method, * Although this is exposed by the json_object_get_array() method,
* it is not recommended for direct use. * 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 #ifdef __cplusplus
extern "C" { extern "C" {


+ 4
- 0
cmake-configure View File

@@ -30,6 +30,7 @@ $0 [<configure_options>] [-- [<cmake options>]]
--enable-static build static libraries [default=yes] --enable-static build static libraries [default=yes]
--disable-Bsymbolic Avoid linking with -Bsymbolic-function --disable-Bsymbolic Avoid linking with -Bsymbolic-function
--disable-werror Avoid treating compiler warnings as fatal errors --disable-werror Avoid treating compiler warnings as fatal errors
--disable-extra-libs Avoid linking against extra libraries, such as libbsd


EOF EOF
exit exit
@@ -73,6 +74,9 @@ while [ $# -gt 0 ] ; do
--disable-werror) --disable-werror)
FLAGS+=(-DDISABLE_WERROR=ON) FLAGS+=(-DDISABLE_WERROR=ON)
;; ;;
--disable-extra-libs)
FLAGS+=(-DDISABLE_EXTRA_LIBS=ON)
;;
--) --)
shift shift
break break


+ 6
- 0
cmake/config.h.in View File

@@ -74,6 +74,12 @@
/* Define to 1 if you have the <xlocale.h> header file. */ /* Define to 1 if you have the <xlocale.h> header file. */
#cmakedefine HAVE_XLOCALE_H #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.' */ /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
#cmakedefine HAVE_DOPRNT #cmakedefine HAVE_DOPRNT




+ 3
- 3
debug.h View File

@@ -14,8 +14,8 @@
* @file * @file
* @brief Do not use, json-c internal, may be changed or removed at any time. * @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> #include <stdlib.h>


@@ -24,7 +24,7 @@ extern "C" {
#endif #endif


#ifndef JSON_EXPORT #ifndef JSON_EXPORT
#if defined(_MSC_VER)
#if defined(_MSC_VER) && defined(JSON_C_DLL)
#define JSON_EXPORT __declspec(dllexport) #define JSON_EXPORT __declspec(dllexport)
#else #else
#define JSON_EXPORT extern #define JSON_EXPORT extern


json.h → json.h.cmakein View File

@@ -26,7 +26,7 @@ extern "C" {
#include "json_c_version.h" #include "json_c_version.h"
#include "json_object.h" #include "json_object.h"
#include "json_object_iterator.h" #include "json_object_iterator.h"
#include "json_pointer.h"
@JSON_H_JSON_POINTER@
#include "json_tokener.h" #include "json_tokener.h"
#include "json_util.h" #include "json_util.h"
#include "linkhash.h" #include "linkhash.h"

+ 1
- 1
json_c_version.h View File

@@ -24,7 +24,7 @@ extern "C" {
#define JSON_C_VERSION "0.15.99" #define JSON_C_VERSION "0.15.99"


#ifndef JSON_EXPORT #ifndef JSON_EXPORT
#if defined(_MSC_VER)
#if defined(_MSC_VER) && defined(JSON_C_DLL)
#define JSON_EXPORT __declspec(dllexport) #define JSON_EXPORT __declspec(dllexport)
#else #else
#define JSON_EXPORT extern #define JSON_EXPORT extern


+ 14
- 13
json_object.c View File

@@ -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) 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; unsigned char c;
while (len--) while (len--)
{ {
@@ -237,7 +237,7 @@ static int json_escape_str(struct printbuf *pb, const char *str, size_t len, int
break; break;
} }


if (pos - start_offset > 0)
if (pos > start_offset)
printbuf_memappend(pb, str + start_offset, pos - start_offset); printbuf_memappend(pb, str + start_offset, pos - start_offset);


if (c == '\b') if (c == '\b')
@@ -263,7 +263,7 @@ static int json_escape_str(struct printbuf *pb, const char *str, size_t len, int
if (c < ' ') if (c < ' ')
{ {
char sbuf[7]; char sbuf[7];
if (pos - start_offset > 0)
if (pos > start_offset)
printbuf_memappend(pb, str + start_offset, printbuf_memappend(pb, str + start_offset,
pos - start_offset); pos - start_offset);
snprintf(sbuf, sizeof(sbuf), "\\u00%c%c", json_hex_chars[c >> 4], 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++; pos++;
} }
} }
if (pos - start_offset > 0)
if (pos > start_offset)
printbuf_memappend(pb, str + start_offset, pos - start_offset); printbuf_memappend(pb, str + start_offset, pos - start_offset);
return 0; 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; struct json_object_string *jso;


/* /*
* Structures Actual memory layout
* ------------------- --------------------
* Structures Actual memory layout
* ------------------- --------------------
* [json_object_string [json_object_string * [json_object_string [json_object_string
* [json_object] [json_object] * [json_object] [json_object]
* ...other fields... ...other fields...
* ...other fields... ...other fields...
* c_string] len * c_string] len
* bytes
* bytes
* of * of
* string * string
* data * data
* \0]
* \0]
*/ */
if (len > (SSIZE_T_MAX - (sizeof(*jso) - sizeof(jso->c_string)) - 1)) if (len > (SSIZE_T_MAX - (sizeof(*jso) - sizeof(jso->c_string)) - 1))
return NULL; 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) if (jso == NULL || jso->o_type != json_type_string)
return 0; 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 // 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; return 0;


dstbuf = get_string_component_mutable(jso); 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 */ /* This handles the `json_type_null` case */
if (!iter.val) if (!iter.val)
jso = NULL; 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) shallow_copy) < 0)
{ {
json_object_put(jso); 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) if (shallow_copy == NULL)
shallow_copy = json_c_shallow_copy_default; 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) if (rc < 0)
{ {
json_object_put(*dst); json_object_put(*dst);


+ 5
- 4
json_object.h View File

@@ -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 * @param val the local name for the json_object* object variable defined in
* the body * 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) \ #define json_object_object_foreach(obj, key, val) \
char *key = NULL; \ char *key = NULL; \
@@ -502,7 +502,7 @@ JSON_EXPORT void json_object_object_del(struct json_object *obj, const char *key
: 0); \ : 0); \
entry##key = entry_next##key) 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) /** Iterate through all keys and values of an object (ANSI C Safe)
* @param obj the json_object instance * @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. * 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 * 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 * 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 * @param obj the json_object instance
* @returns a json_bool * @returns a json_bool


+ 6
- 0
json_tokener.c View File

@@ -155,6 +155,12 @@ struct json_tokener *json_tokener_new_ex(int depth)
return NULL; return NULL;
} }
tok->pb = printbuf_new(); tok->pb = printbuf_new();
if (!tok->pb)
{
free(tok);
free(tok->stack);
return NULL;
}
tok->max_depth = depth; tok->max_depth = depth;
json_tokener_reset(tok); json_tokener_reset(tok);
return tok; return tok;


+ 1
- 1
json_types.h View File

@@ -18,7 +18,7 @@ extern "C" {
#endif #endif


#ifndef JSON_EXPORT #ifndef JSON_EXPORT
#if defined(_MSC_VER)
#if defined(_MSC_VER) && defined(JSON_C_DLL)
#define JSON_EXPORT __declspec(dllexport) #define JSON_EXPORT __declspec(dllexport)
#else #else
#define JSON_EXPORT extern #define JSON_EXPORT extern


+ 2
- 2
linkhash.h View File

@@ -16,8 +16,8 @@
* this is exposed by the json_object_get_object() function and within the * this is exposed by the json_object_get_object() function and within the
* json_object_iter type, it is not recommended for direct use. * 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" #include "json_object.h"




+ 3
- 3
printbuf.h View File

@@ -20,11 +20,11 @@
* json_object_set_serializer() direct use of this is not * json_object_set_serializer() direct use of this is not
* recommended. * recommended.
*/ */
#ifndef _printbuf_h_
#define _printbuf_h_
#ifndef _json_c_printbuf_h_
#define _json_c_printbuf_h_


#ifndef JSON_EXPORT #ifndef JSON_EXPORT
#if defined(_MSC_VER)
#if defined(_MSC_VER) && defined(JSON_C_DLL)
#define JSON_EXPORT __declspec(dllexport) #define JSON_EXPORT __declspec(dllexport)
#else #else
#define JSON_EXPORT extern #define JSON_EXPORT extern


+ 62
- 44
random_seed.c View File

@@ -13,9 +13,23 @@
#include "config.h" #include "config.h"
#include "strerror_override.h" #include "strerror_override.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_BSD_STDLIB_H
#include <bsd/stdlib.h>
#endif


#define DEBUG_SEED(s) #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 #if defined ENABLE_RDRAND


/* cpuid */ /* cpuid */
@@ -162,36 +176,38 @@ retry:
#include <sys/random.h> #include <sys/random.h>
#endif #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; ssize_t ret;


do {
ret = getrandom(&r, sizeof(r), 0);
do
{
ret = getrandom(seed, sizeof(*seed), GRND_NONBLOCK);
} while ((ret == -1) && (errno == EINTR)); } while ((ret == -1) && (errno == EINTR));


if (ret == -1) if (ret == -1)
{ {
if (errno == ENOSYS) /* syscall not available in kernel */ if (errno == ENOSYS) /* syscall not available in kernel */
return -1; return -1;
if (errno == EAGAIN) /* entropy not yet initialized */
return -1;


fprintf(stderr, "error from getrandom(): %s", strerror(errno)); fprintf(stderr, "error from getrandom(): %s", strerror(errno));
exit(1);
return -1;
} }


if (ret != sizeof(r))
if (ret != sizeof(*seed))
return -1; return -1;


return r;
return 0;
} }
#endif /* defined HAVE_GETRANDOM */ #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 <fcntl.h>
#include <string.h> #include <string.h>
@@ -201,43 +217,34 @@ static int get_getrandom_seed(void)
#include <stdlib.h> #include <stdlib.h>
#include <sys/stat.h> #include <sys/stat.h>


#define HAVE_DEV_RANDOM 1

static const char *dev_random_file = "/dev/urandom"; 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; struct stat buf;
if (stat(dev_random_file, &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); int fd = open(dev_random_file, O_RDONLY);
if (fd < 0) if (fd < 0)
{ {
fprintf(stderr, "error opening %s: %s", dev_random_file, strerror(errno)); 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)); fprintf(stderr, "error short read %s: %s", dev_random_file, strerror(errno));
exit(1);
return -1;
} }


close(fd); close(fd);
return r;
return 0;
} }


#endif #endif
@@ -260,13 +267,10 @@ static int get_dev_random_seed(void)
#pragma comment(lib, "advapi32.lib") #pragma comment(lib, "advapi32.lib")
#endif #endif


static int get_time_seed(void);

static int get_cryptgenrandom_seed(void)
static int get_cryptgenrandom_seed(int *seed)
{ {
HCRYPTPROV hProvider = 0; HCRYPTPROV hProvider = 0;
DWORD dwFlags = CRYPT_VERIFYCONTEXT; DWORD dwFlags = CRYPT_VERIFYCONTEXT;
int r;


DEBUG_SEED("get_cryptgenrandom_seed"); DEBUG_SEED("get_cryptgenrandom_seed");


@@ -277,34 +281,36 @@ static int get_cryptgenrandom_seed(void)
if (!CryptAcquireContextA(&hProvider, 0, 0, PROV_RSA_FULL, dwFlags)) if (!CryptAcquireContextA(&hProvider, 0, 0, PROV_RSA_FULL, dwFlags))
{ {
fprintf(stderr, "error CryptAcquireContextA 0x%08lx", GetLastError()); fprintf(stderr, "error CryptAcquireContextA 0x%08lx", GetLastError());
r = get_time_seed();
return -1;
} }
else else
{ {
BOOL ret = CryptGenRandom(hProvider, sizeof(r), (BYTE*)&r);
BOOL ret = CryptGenRandom(hProvider, sizeof(*seed), (BYTE *)seed);
CryptReleaseContext(hProvider, 0); CryptReleaseContext(hProvider, 0);
if (!ret) if (!ret)
{ {
fprintf(stderr, "error CryptGenRandom 0x%08lx", GetLastError()); fprintf(stderr, "error CryptGenRandom 0x%08lx", GetLastError());
r = get_time_seed();
return -1;
} }
} }


return r;
return 0;
} }


#endif #endif


/* get_time_seed */ /* get_time_seed */


#ifndef HAVE_ARC4RANDOM
#include <time.h> #include <time.h>


static int get_time_seed(void) static int get_time_seed(void)
{ {
DEBUG_SEED("get_time_seed"); DEBUG_SEED("get_time_seed");


return (int)time(NULL) * 433494437;
return (unsigned)time(NULL) * 433494437;
} }
#endif


/* json_c_get_random_seed */ /* json_c_get_random_seed */


@@ -317,19 +323,31 @@ int json_c_get_random_seed(void)
if (has_rdrand()) if (has_rdrand())
return get_rdrand_seed(); return get_rdrand_seed();
#endif #endif
#ifdef HAVE_ARC4RANDOM
/* arc4random never fails, so use it if it's available */
return arc4random();
#else
#ifdef HAVE_GETRANDOM #ifdef HAVE_GETRANDOM
{ {
int seed = get_getrandom_seed();
if (seed != -1)
int seed;
if (get_getrandom_seed(&seed) == 0)
return seed; return seed;
} }
#endif #endif
#if defined HAVE_DEV_RANDOM && HAVE_DEV_RANDOM #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 #endif
#if defined HAVE_CRYPTGENRANDOM && HAVE_CRYPTGENRANDOM #if defined HAVE_CRYPTGENRANDOM && HAVE_CRYPTGENRANDOM
return get_cryptgenrandom_seed();
{
int seed;
if (get_cryptgenrandom_seed(&seed) == 0)
return seed;
}
#endif #endif
return get_time_seed(); return get_time_seed();
#endif /* !HAVE_ARC4RANDOM */
} }

+ 2
- 1
strerror_override.c View File

@@ -94,7 +94,7 @@ char *_json_c_strerror(int errno_in)
} }


// It's not one of the known errno values, return the numeric value. // 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)]; 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] = digbuf[ii];
} }
errno_buf[start_idx] = '\0';
return errno_buf; return errno_buf;
} }

+ 30
- 24
tests/CMakeLists.txt View File

@@ -12,32 +12,38 @@ target_link_libraries(test2Formatted PRIVATE ${PROJECT_NAME})


include_directories(PUBLIC ${CMAKE_SOURCE_DIR}) 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) 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: # For output consistency, we need _json_c_strerror() in some tests:
target_sources(${TESTNAME} PRIVATE ../strerror_override.c) target_sources(${TESTNAME} PRIVATE ../strerror_override.c)
endif() endif()


+ 24
- 0
tests/test1.c View File

@@ -1,9 +1,12 @@
#include <assert.h> #include <assert.h>
#include <limits.h>
#include <stddef.h> #include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>


#include "config.h"

#include "json.h" #include "json.h"
#include "parse_flags.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)); 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_string);
json_object_put(my_int); json_object_put(my_int);
json_object_put(my_null); json_object_put(my_null);


+ 10
- 0
tests/test_cast.c View File

@@ -28,6 +28,11 @@ int main(int argc, char **argv)
\"int64_number\": 2147483649,\n\ \"int64_number\": 2147483649,\n\
\"negative_number\": -321321321,\n\ \"negative_number\": -321321321,\n\
\"a_null\": null,\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: 2147483649 = INT_MAX + 2 */
/* Note: 9223372036854775809 = INT64_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, "int64_number");
getit(new_obj, "negative_number"); getit(new_obj, "negative_number");
getit(new_obj, "a_null"); 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. // Now check the behaviour of the json_object_is_type() function.
printf("\n================================\n"); printf("\n================================\n");


+ 35
- 0
tests/test_cast.expected View File

@@ -7,6 +7,11 @@ Parsed input: {
"int64_number": 2147483649, "int64_number": 2147483649,
"negative_number": -321321321, "negative_number": -321321321,
"a_null": null, "a_null": null,
"empty_array": [],
"nonempty_array": [ 123 ],
"array_with_zero": [ 0 ],
"empty_object": {},
"nonempty_object": { "a": 123 },
} }
Result is not NULL Result is not NULL
new_obj.string_of_digits json_object_get_type()=string 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_uint64()=0
new_obj.a_null json_object_get_boolean()=0 new_obj.a_null json_object_get_boolean()=0
new_obj.a_null json_object_get_double()=0.000000 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 json_object_is_type: null,boolean,double,int,object,array,string


+ 11
- 0
tests/test_strerror.c View File

@@ -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;
}

+ 2
- 0
tests/test_strerror.expected View File

@@ -0,0 +1,2 @@
ERRNO=10000
ERRNO=999

+ 1
- 0
tests/test_strerror.test View File

@@ -0,0 +1 @@
test_basic.test

Loading…
Cancel
Save