From 4e9e44e5258dee7654f74948b0dd5da39c28beec Mon Sep 17 00:00:00 2001 From: Marc <34656315+MarcT512@users.noreply.github.com> Date: Fri, 7 Aug 2020 10:49:45 +0100 Subject: [PATCH 01/27] Fix read past end of buffer Resolves https://github.com/json-c/json-c/issues/654 --- apps/json_parse.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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, From 0ffb38440935b2c71fa4851d2f44f2d120f24735 Mon Sep 17 00:00:00 2001 From: Aram Poghosyan Date: Fri, 14 Aug 2020 11:45:33 +0400 Subject: [PATCH 02/27] Fixed warnings --- json_object.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/json_object.c b/json_object.c index 9198257..6c572a8 100644 --- a/json_object.c +++ b/json_object.c @@ -1724,7 +1724,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); @@ -1789,7 +1789,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); From f052e42f56eae6b8a5b3833731e1d85e054fa09e Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Sat, 15 Aug 2020 15:41:41 +0200 Subject: [PATCH 03/27] Use GRND_NONBLOCK with getrandom. The json-c library is used in cryptsetup for LUKS2 header information. Since cryptsetup can be called very early during boot, the developers avoid getrandom() calls in their own code base for now. [1] Introducing a blocking getrandom() call in json-c therefore introduces this issue for cryptsetup as well. Even though cryptsetup issues do not have to be json-c issues, here is my proposal: Let's use a non-blocking call, falling back to other sources if the call would block. Since getrandom() accesses urandom, it must mean that we are in an early boot phase -- otherwise the call would not block according to its manual page. As stated in manual page of random(4), accessing /dev/urandom won't block but return weak random numbers, therefore this fallback would work for json-c. While at it, fixed the debug message. [1] https://gitlab.com/cryptsetup/cryptsetup/-/merge_requests/47 which references to https://lwn.net/Articles/800509/ --- random_seed.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/random_seed.c b/random_seed.c index 17727c6..c428da9 100644 --- a/random_seed.c +++ b/random_seed.c @@ -164,19 +164,21 @@ retry: static int get_getrandom_seed(void) { - DEBUG_SEED("get_dev_random_seed"); + DEBUG_SEED("get_getrandom_seed"); int r; ssize_t ret; do { - ret = getrandom(&r, sizeof(r), 0); + ret = getrandom(&r, sizeof(r), 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); From 2b439ea59857747067e8272011ad67303e0d4cf1 Mon Sep 17 00:00:00 2001 From: Eric Haszlakiewicz Date: Mon, 17 Aug 2020 14:55:54 +0000 Subject: [PATCH 04/27] Fix json_object_get_boolean() doc for the object and array cases (always returns 0), and add those cases to the test_cast test. See also issue #658. --- json_object.h | 5 +++-- tests/test_cast.c | 10 ++++++++++ tests/test_cast.expected | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/json_object.h b/json_object.h index a54541c..036be64 100644 --- a/json_object.h +++ b/json_object.h @@ -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/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 From 4298431150df9a83390a14006217c230e684994b Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Sat, 22 Aug 2020 11:35:50 +0200 Subject: [PATCH 05/27] Properly format errnos in _json_c_strerror The function _json_c_strerror does not properly format unknown errnos. The int to ascii loop ignores the leading digit if the number can be divided by 10 and if an errno has been formatted, shorter errnos would not properly terminate the newly created string, showing the ending numbers of the previous output. A test case has been added to show these effects. Since this function has been introduced for tests, the effect of this on real life code is basically non-existing. First an environment variable has to be set to activate this strerror code and second an unknown errno would have to be encountered. --- strerror_override.c | 3 ++- tests/CMakeLists.txt | 3 ++- tests/test_strerror.c | 11 +++++++++++ tests/test_strerror.expected | 2 ++ tests/test_strerror.test | 1 + 5 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 tests/test_strerror.c create mode 100644 tests/test_strerror.expected create mode 120000 tests/test_strerror.test 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..0c5c26e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -32,12 +32,13 @@ foreach(TESTNAME test_printbuf test_set_serializer test_set_value + test_strerror test_util_file test_visit test_object_iterator) 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/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 + +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 From 583911a66c5b1103e7c98e59ef165631c0cbf290 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Sat, 22 Aug 2020 13:07:45 +0200 Subject: [PATCH 06/27] Aligned comment in _json_object_new_string The comment only aligns correctly if tab size is 4. Replaced spaces with tabs to stay in sync with style of other lines. --- json_object.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/json_object.c b/json_object.c index 6c572a8..f8d14d5 100644 --- a/json_object.c +++ b/json_object.c @@ -1254,17 +1254,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; From e50154f615cbd2a14857a6f68462e3a699be42d8 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Sat, 22 Aug 2020 13:09:11 +0200 Subject: [PATCH 07/27] Cap string length at INT_MAX. Several issues occur if a string is longer than INT_MAX: - The function json_object_get_string_len returns the length of a string as int. If the string is longer than INT_MAX, the result would be negative. - That in turn would lead to possible out of boundary access when comparing these strings with memcmp and the returned length as done in json_object_equal. - If json_escape_str is called with such strings, out of boundary accesses can occur due to internal int handling (also fixed). - The string cannot be printed out due to printbuffer limits at INT_MAX (which is still true after this commit). Such huge strings can only be inserted through API calls at this point because input files are capped at INT_MAX anyway. Due to huge amount of RAM needed to reproduce these issues I have not added test cases. --- json_object.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/json_object.c b/json_object.c index f8d14d5..b42026b 100644 --- a/json_object.c +++ b/json_object.c @@ -214,7 +214,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--) { @@ -1329,9 +1329,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); From bcb6d7d3474b687718cbaee7bf203db4456fb6b3 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Sat, 22 Aug 2020 13:18:10 +0200 Subject: [PATCH 08/27] Handle allocation failure in json_tokener_new_ex The allocation of printbuf_new might fail. Return NULL to indicate tis error to the caller. Otherwise later usage of the returned tokener would lead to null pointer dereference. --- json_tokener.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/json_tokener.c b/json_tokener.c index 6527270..aad463a 100644 --- a/json_tokener.c +++ b/json_tokener.c @@ -134,6 +134,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; From df62119b7f11dbd97715668a6311410f67bea3c9 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Sat, 22 Aug 2020 13:23:23 +0200 Subject: [PATCH 09/27] Prevent signed overflow in get_time_seed Casting time(2) return value to int and multiplying the result with such a constant will definitely lead to a signed overflow by this day. Since signed overflows are undefined behaviour in C, avoid this. Casting to unsigned is more than enough since the upper bits of a 64 bit time_t value will be removed with the int conversion anyway. --- random_seed.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/random_seed.c b/random_seed.c index c428da9..b4c0afd 100644 --- a/random_seed.c +++ b/random_seed.c @@ -305,7 +305,7 @@ static int get_time_seed(void) { DEBUG_SEED("get_time_seed"); - return (int)time(NULL) * 433494437; + return (unsigned)time(NULL) * 433494437; } /* json_c_get_random_seed */ From 369e8477d25132e9eeefb89ae1dacb3c4a738652 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Sat, 22 Aug 2020 12:06:15 +0200 Subject: [PATCH 10/27] Validate size arguments in arraylist functions. The array_list_new2 function, which is externally reachable through json_object_new_array_ext, does not check if specified initial size actually fits into memory on 32 bit architectures. It also allows negative values, which could lead to an overflow on these architectures as well. I have added test cases for these situations. While at it, also protect array_list_shrink against too large empty_slots argument. No test added because it takes a huge length value, therefore a lot of items within the array, to overflow the calculation. In theory this affects 64 bit sytems as well, but since the arraylist API is not supposed to be used by external applications according to its header file, the call is protected due to int limitation of json_object_array_shrink. --- arraylist.c | 4 ++++ tests/test1.c | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+) 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/tests/test1.c b/tests/test1.c index 6682120..7e41610 100644 --- a/tests/test1.c +++ b/tests/test1.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -307,6 +308,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); From 7af593c140523efa04e863f3772f0632c7ffcde3 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Fri, 11 Sep 2020 21:09:40 +0200 Subject: [PATCH 11/27] Fixed test1 regression. SIZEOF_SIZE_T might be only defined in config.h. Include config.h for these systems to pass tests which are only supposed to be run on 32 bit systems. Fixes issue #666. --- tests/test1.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test1.c b/tests/test1.c index 7e41610..4d29601 100644 --- a/tests/test1.c +++ b/tests/test1.c @@ -5,6 +5,8 @@ #include #include +#include "config.h" + #include "json.h" #include "parse_flags.h" From 0fd3b7d316bcfbca2bac875eea396fbc9cf08b33 Mon Sep 17 00:00:00 2001 From: Pierce Lopez Date: Wed, 7 Oct 2020 01:22:30 -0400 Subject: [PATCH 12/27] random_seed: on error, continue to next method instead of exiting the process --- random_seed.c | 69 ++++++++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 40 deletions(-) diff --git a/random_seed.c b/random_seed.c index b4c0afd..ff5338f 100644 --- a/random_seed.c +++ b/random_seed.c @@ -162,15 +162,14 @@ retry: #include #endif -static int get_getrandom_seed(void) +static int get_getrandom_seed(int *seed) { DEBUG_SEED("get_getrandom_seed"); - int r; ssize_t ret; do { - ret = getrandom(&r, sizeof(r), GRND_NONBLOCK); + ret = getrandom(seed, sizeof(*seed), GRND_NONBLOCK); } while ((ret == -1) && (errno == EINTR)); if (ret == -1) @@ -181,17 +180,17 @@ static int get_getrandom_seed(void) 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__) @@ -207,39 +206,32 @@ static int get_getrandom_seed(void) 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 @@ -262,9 +254,7 @@ 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; @@ -279,20 +269,20 @@ 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 @@ -312,6 +302,7 @@ static int get_time_seed(void) int json_c_get_random_seed(void) { + int seed; #ifdef OVERRIDE_GET_RANDOM_SEED OVERRIDE_GET_RANDOM_SEED; #endif @@ -320,18 +311,16 @@ int json_c_get_random_seed(void) return get_rdrand_seed(); #endif #ifdef HAVE_GETRANDOM - { - int seed = get_getrandom_seed(); - if (seed != -1) - return 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(); + if (get_dev_random_seed(&seed) == 0) + return seed; #endif #if defined HAVE_CRYPTGENRANDOM && HAVE_CRYPTGENRANDOM - return get_cryptgenrandom_seed(); + if (get_cryptgenrandom_seed(&seed) == 0) + return seed; #endif return get_time_seed(); } From 987d3b2c86748299f2ceb83345264c6aaa8e1db6 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Thu, 17 Dec 2020 19:59:37 -0800 Subject: [PATCH 13/27] fix compilation with clang Fixes the following warning: json_pointer.c:230:7: warning: implicit declaration of function 'vasprintf' is invalid in C99 [-Wimplicit-function-declaration] rc = vasprintf(&path_copy, path_fmt, args); --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2333d08..892aebb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -269,7 +269,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") From 69d650528da0e23654065f4efc26c469bdae663c Mon Sep 17 00:00:00 2001 From: Eric Haszlakiewicz Date: Wed, 13 Jan 2021 01:30:16 +0000 Subject: [PATCH 14/27] Keep the doc directory in the nodoc release tarball, just exclude its contents. --- RELEASE_CHECKLIST.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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} ------------ From 0f61f6921b2e4395d1e354ad356137e44d6a7e11 Mon Sep 17 00:00:00 2001 From: Eric Haszlakiewicz Date: Wed, 13 Jan 2021 01:57:25 +0000 Subject: [PATCH 15/27] Iesue #692: use arc4random() if it's available (in libc on BSD systems, and libbsd on Linux). --- CMakeLists.txt | 11 +++++++++++ cmake/config.h.in | 6 ++++++ random_seed.c | 13 +++++++++++-- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 892aebb..30b4f2d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -170,6 +170,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) + 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() 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 header file. */ #cmakedefine HAVE_XLOCALE_H +/* Define to 1 if you have the 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 diff --git a/random_seed.c b/random_seed.c index ff5338f..f3ee740 100644 --- a/random_seed.c +++ b/random_seed.c @@ -13,6 +13,10 @@ #include "config.h" #include "strerror_override.h" #include +#include +#ifdef HAVE_BSD_STDLIB_H +#include +#endif #define DEBUG_SEED(s) @@ -168,7 +172,8 @@ static int get_getrandom_seed(int *seed) ssize_t ret; - do { + do + { ret = getrandom(seed, sizeof(*seed), GRND_NONBLOCK); } while ((ret == -1) && (errno == EINTR)); @@ -273,7 +278,7 @@ static int get_cryptgenrandom_seed(int *seed) } else { - BOOL ret = CryptGenRandom(hProvider, sizeof(*seed), (BYTE*)seed); + BOOL ret = CryptGenRandom(hProvider, sizeof(*seed), (BYTE *)seed); CryptReleaseContext(hProvider, 0); if (!ret) { @@ -310,6 +315,10 @@ 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(); +#endif #ifdef HAVE_GETRANDOM if (get_getrandom_seed(&seed) == 0) return seed; From c456963110fa5af9a209218c718d81033ad53669 Mon Sep 17 00:00:00 2001 From: ihsinme <61293369+ihsinme@users.noreply.github.com> Date: Fri, 5 Feb 2021 18:58:20 +0300 Subject: [PATCH 16/27] Update json_object.c --- json_object.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/json_object.c b/json_object.c index b42026b..c15a477 100644 --- a/json_object.c +++ b/json_object.c @@ -235,7 +235,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') @@ -261,7 +261,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], @@ -273,7 +273,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; } From f787810890b91b2b141ce7630d5be85c5f8cfcc3 Mon Sep 17 00:00:00 2001 From: Eric Haszlakiewicz Date: Sat, 13 Feb 2021 03:23:58 +0000 Subject: [PATCH 17/27] If arc4random is used, don't bother compiling in the other fallback methods since they'll never be used. Fixes PR#695 about unreachable code too. --- random_seed.c | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/random_seed.c b/random_seed.c index f3ee740..b2e8ce6 100644 --- a/random_seed.c +++ b/random_seed.c @@ -20,6 +20,16 @@ #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 */ @@ -197,7 +207,7 @@ static int get_getrandom_seed(int *seed) /* get_dev_random_seed */ -#if defined(__APPLE__) || defined(__unix__) || defined(__linux__) +#ifdef HAVE_DEV_RANDOM #include #include @@ -207,8 +217,6 @@ static int get_getrandom_seed(int *seed) #include #include -#define HAVE_DEV_RANDOM 1 - static const char *dev_random_file = "/dev/urandom"; static int get_dev_random_seed(int *seed) @@ -294,6 +302,7 @@ static int get_cryptgenrandom_seed(int *seed) /* get_time_seed */ +#ifndef HAVE_ARC4RANDOM #include static int get_time_seed(void) @@ -302,12 +311,12 @@ static int get_time_seed(void) return (unsigned)time(NULL) * 433494437; } +#endif /* json_c_get_random_seed */ int json_c_get_random_seed(void) { - int seed; #ifdef OVERRIDE_GET_RANDOM_SEED OVERRIDE_GET_RANDOM_SEED; #endif @@ -318,18 +327,28 @@ int json_c_get_random_seed(void) #ifdef HAVE_ARC4RANDOM /* arc4random never fails, so use it if it's available */ return arc4random(); -#endif +#else #ifdef HAVE_GETRANDOM - if (get_getrandom_seed(&seed) == 0) - return seed; + { + int seed; + if (get_getrandom_seed(&seed) == 0) + return seed; + } #endif #if defined HAVE_DEV_RANDOM && HAVE_DEV_RANDOM - if (get_dev_random_seed(&seed) == 0) - return seed; + { + int seed; + if (get_dev_random_seed(&seed) == 0) + return seed; + } #endif #if defined HAVE_CRYPTGENRANDOM && HAVE_CRYPTGENRANDOM - if (get_cryptgenrandom_seed(&seed) == 0) - return seed; + { + int seed; + if (get_cryptgenrandom_seed(&seed) == 0) + return seed; + } #endif return get_time_seed(); +#endif /* !HAVE_ARC4RANDOM */ } From 041cef434afe0d0c6da8b6ac1d1fa26087246dda Mon Sep 17 00:00:00 2001 From: Eric Haszlakiewicz Date: Mon, 15 Feb 2021 20:19:56 +0000 Subject: [PATCH 18/27] Add a DISABLE_EXTRA_LIBS option to skip using libbsd, per @neheb's request on issue #692/commit 0f61f692. --- CMakeLists.txt | 3 ++- cmake-configure | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 30b4f2d..79038aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,6 +97,7 @@ 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) if (UNIX OR MINGW OR CYGWIN) @@ -171,7 +172,7 @@ 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) +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") diff --git a/cmake-configure b/cmake-configure index c8e44ae..dc695e5 100755 --- a/cmake-configure +++ b/cmake-configure @@ -30,6 +30,7 @@ $0 [] [-- []] --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 From ba181548bca566d320899f7b78e5b753c0dba611 Mon Sep 17 00:00:00 2001 From: ssrlive <30760636+ssrlive@users.noreply.github.com> Date: Tue, 2 Mar 2021 14:27:40 +0800 Subject: [PATCH 19/27] To avoid target exe file export JSON functions. --- CMakeLists.txt | 4 ++++ debug.h | 2 +- json_c_version.h | 2 +- json_types.h | 2 +- printbuf.h | 2 +- 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 79038aa..60fa7e1 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 diff --git a/debug.h b/debug.h index a24136b..7463f86 100644 --- a/debug.h +++ b/debug.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 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_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 diff --git a/printbuf.h b/printbuf.h index bfcbd2b..a0da668 100644 --- a/printbuf.h +++ b/printbuf.h @@ -24,7 +24,7 @@ #define _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 From 9c0565100afde7d40ef0a6b34e9df2bfe84f2735 Mon Sep 17 00:00:00 2001 From: Philosoph228 Date: Tue, 13 Apr 2021 00:12:35 +0500 Subject: [PATCH 20/27] random_seed: fix unused variable for win32 build --- random_seed.c | 1 - 1 file changed, 1 deletion(-) diff --git a/random_seed.c b/random_seed.c index b2e8ce6..f474e39 100644 --- a/random_seed.c +++ b/random_seed.c @@ -271,7 +271,6 @@ static int get_cryptgenrandom_seed(int *seed) { HCRYPTPROV hProvider = 0; DWORD dwFlags = CRYPT_VERIFYCONTEXT; - int r; DEBUG_SEED("get_cryptgenrandom_seed"); From 1f8b64f62c76cb23a8eb041fdde341db604aae75 Mon Sep 17 00:00:00 2001 From: Alexandru Ardelean Date: Fri, 16 Apr 2021 09:32:07 +0300 Subject: [PATCH 21/27] tests: CMakeLists.txt: move test names to variable The intent is to be able to disable some features that get built into the library. When we do that, we also need to disable some tests. It's easier when adjusting a variable that contains the list of test names, versus modifying the list in the foreach() statement. Signed-off-by: Alexandru Ardelean --- tests/CMakeLists.txt | 50 +++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 0c5c26e..cccb5df 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -12,30 +12,32 @@ 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_strerror - 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_json_pointer + 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) + +foreach(TESTNAME ${ALL_TEST_NAMES}) add_executable(${TESTNAME} ${TESTNAME}.c) if(${TESTNAME} STREQUAL test_strerror OR ${TESTNAME} STREQUAL test_util_file) From 8abeebc9b20ee830867df1c21cfa87bd6fdbaa38 Mon Sep 17 00:00:00 2001 From: Alexandru Ardelean Date: Fri, 16 Apr 2021 09:42:07 +0300 Subject: [PATCH 22/27] json_pointer: allow the feature to be disabled Some users may not want to included it in their build/system. So allow a cmake symbol to disable it. A user can do 'cmake -DDISABLE_JSON_POINTER=ON ' and disable the json_pointer functionality. That saves about 17 KB (on an x86_64) machine. This may be useful on smaller embedded systems; even though the saving would be fewer kilobytes. One thing that also needs to change a bit, is that the 'json.h' be autogenerated via cmake, in order to conditionally include that "json_pointer.h" file. Signed-off-by: Alexandru Ardelean --- .gitignore | 1 + CMakeLists.txt | 15 ++++++++++++--- json.h => json.h.cmakein | 2 +- tests/CMakeLists.txt | 5 ++++- 4 files changed, 18 insertions(+), 5 deletions(-) rename json.h => json.h.cmakein (96%) diff --git a/.gitignore b/.gitignore index 1cdaf9b..8d2cb62 100644 --- a/.gitignore +++ b/.gitignore @@ -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 79038aa..887b4d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,6 +98,7 @@ option(ENABLE_RDRAND "Enable RDRAND Hardware RNG Hash Seed." 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) @@ -370,14 +371,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 @@ -404,7 +404,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 @@ -414,6 +413,16 @@ 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}) diff --git a/json.h b/json.h.cmakein similarity index 96% rename from json.h rename to json.h.cmakein index 6c3b43b..4fed013 100644 --- a/json.h +++ b/json.h.cmakein @@ -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/tests/CMakeLists.txt b/tests/CMakeLists.txt index cccb5df..d7abf51 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -24,7 +24,6 @@ set(ALL_TEST_NAMES test_double_serializer test_float test_int_add - test_json_pointer test_locale test_null test_parse @@ -37,6 +36,10 @@ set(ALL_TEST_NAMES 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) From 9b53c92ea398c479f59f77b2cbd24d2ccf1fc29a Mon Sep 17 00:00:00 2001 From: David McCann Date: Thu, 13 May 2021 06:31:18 +0100 Subject: [PATCH 23/27] Check __STDC_VERSION__ is defined before checking its value Prevent an undef warning regarding __STDC_VERSION__ by checking whether it is defined before checking its value. --- json_object.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/json_object.h b/json_object.h index 7c0d1f2..be6919a 100644 --- a/json_object.h +++ b/json_object.h @@ -452,7 +452,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; \ @@ -484,7 +484,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 From 9ca50cf2f81ff66b9f0cf9b5c418cafafce82715 Mon Sep 17 00:00:00 2001 From: Eric Haszlakiewicz Date: Wed, 2 Jun 2021 23:53:23 +0000 Subject: [PATCH 24/27] Issue #709: adjust some include guards to be a bit more json-c specific. --- arraylist.h | 4 ++-- debug.h | 4 ++-- linkhash.h | 4 ++-- printbuf.h | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) 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/debug.h b/debug.h index 7463f86..4af0ba9 100644 --- a/debug.h +++ b/debug.h @@ -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 diff --git a/linkhash.h b/linkhash.h index 414599d..0ddfa54 100644 --- a/linkhash.h +++ b/linkhash.h @@ -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" diff --git a/printbuf.h b/printbuf.h index a0da668..9b33802 100644 --- a/printbuf.h +++ b/printbuf.h @@ -20,8 +20,8 @@ * 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) && defined(JSON_C_DLL) From 75bf657cc285c1b726492ed6af3645ea95fe17ac Mon Sep 17 00:00:00 2001 From: Eric Haszlakiewicz Date: Sun, 13 Jun 2021 21:12:22 +0000 Subject: [PATCH 25/27] If inttypes.h is present, use it, even on Windows. --- CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e870cca..01d37f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -154,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() From 9dde931a1c3aa4fd9ffc0be910ee03dceda156f8 Mon Sep 17 00:00:00 2001 From: Hex052 Date: Sun, 4 Jul 2021 18:28:21 -0800 Subject: [PATCH 26/27] Add AfterCaseLabel to .clang-format This is to fix the behavior that might've changed between older versions of clang-format, I'm not sure. Version 10 tries to put the bracket on the same line as case without this. --- .clang-format | 2 ++ 1 file changed, 2 insertions(+) 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 From 8c727e5ce13b288d982471120b19c037a1cb9624 Mon Sep 17 00:00:00 2001 From: Eric Haszlakiewicz Date: Sun, 25 Jul 2021 15:11:11 +0000 Subject: [PATCH 27/27] Only define an "uninstall" target if it's not already defined (e.g. by projects that include json-c) --- CMakeLists.txt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 01d37f8..ed7bc03 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -436,10 +436,12 @@ 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.