From 55c597c719fcadb7e4963c2b9f819e0e0e00a699 Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Thu, 28 Dec 2017 12:45:28 +0100 Subject: [PATCH 1/6] add_item_to_array with boolean return value --- cJSON.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/cJSON.c b/cJSON.c index d08cb5b..98f7081 100644 --- a/cJSON.c +++ b/cJSON.c @@ -1844,14 +1844,13 @@ static cJSON *create_reference(const cJSON *item, const internal_hooks * const h return reference; } -/* Add item to array/object. */ -CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item) +static cJSON_bool add_item_to_array(cJSON *array, cJSON *item) { cJSON *child = NULL; if ((item == NULL) || (array == NULL)) { - return; + return false; } child = array->child; @@ -1870,6 +1869,14 @@ CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item) } suffix_object(child, item); } + + return true; +} + +/* Add item to array/object. */ +CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item) +{ + add_item_to_array(array, item); } CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) @@ -1913,7 +1920,7 @@ CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJ } item->string = (char*)cast_away_const(string); item->type |= cJSON_StringIsConst; - cJSON_AddItemToArray(object, item); + add_item_to_array(object, item); } CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) @@ -1923,7 +1930,7 @@ CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) return; } - cJSON_AddItemToArray(array, create_reference(item, &global_hooks)); + add_item_to_array(array, create_reference(item, &global_hooks)); } CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item) @@ -2018,7 +2025,7 @@ CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newit after_inserted = get_array_item(array, (size_t)which); if (after_inserted == NULL) { - cJSON_AddItemToArray(array, newitem); + add_item_to_array(array, newitem); return; } From de729a1635503af70b7b285dc167503c34b5be06 Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Thu, 28 Dec 2017 17:19:03 +0100 Subject: [PATCH 2/6] Extract add_item_to_object function that returns a boolean --- cJSON.c | 65 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/cJSON.c b/cJSON.c index 98f7081..79ce826 100644 --- a/cJSON.c +++ b/cJSON.c @@ -1879,19 +1879,6 @@ CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item) add_item_to_array(array, item); } -CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) -{ - if (item == NULL) - { - return; - } - - /* call cJSON_AddItemToObjectCS for code reuse */ - cJSON_AddItemToObjectCS(object, (char*)cJSON_strdup((const unsigned char*)string, &global_hooks), item); - /* remove cJSON_StringIsConst flag */ - item->type &= ~cJSON_StringIsConst; -} - #if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) #pragma GCC diagnostic push #endif @@ -1907,20 +1894,48 @@ static void* cast_away_const(const void* string) #pragma GCC diagnostic pop #endif + +static cJSON_bool add_item_to_object(cJSON * const object, const char * const string, cJSON * const item, const internal_hooks * const hooks, const cJSON_bool constant_key) +{ + if ((object == NULL) || (string == NULL) || (item == NULL)) + { + return false; + } + + if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) + { + hooks->deallocate(item->string); + } + + if (constant_key) + { + item->string = (char*)cast_away_const(string); + item->type |= cJSON_StringIsConst; + } + else + { + char *key = (char*)cJSON_strdup((const unsigned char*)string, hooks); + if (key == NULL) + { + return false; + } + + item->string = key; + item->type &= ~cJSON_StringIsConst; + } + + return add_item_to_array(object, item); +} + +CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) +{ + add_item_to_object(object, string, item, &global_hooks, false); +} + /* Add an item to an object with constant string as key */ CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item) { - if ((item == NULL) || (string == NULL)) - { - return; - } - if (!(item->type & cJSON_StringIsConst) && item->string) - { - global_hooks.deallocate(item->string); - } - item->string = (char*)cast_away_const(string); - item->type |= cJSON_StringIsConst; - add_item_to_array(object, item); + add_item_to_object(object, string, item, &global_hooks, true); } CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) @@ -1940,7 +1955,7 @@ CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *str return; } - cJSON_AddItemToObject(object, string, create_reference(item, &global_hooks)); + add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false); } CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item) From f966409b33ef07bcc6beb2416eeaee4181b622e1 Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Thu, 28 Dec 2017 22:56:57 +0100 Subject: [PATCH 3/6] Add tests for cJSON_Add...ToObject macros --- tests/CMakeLists.txt | 1 + tests/cjson_add.c | 145 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 tests/cjson_add.c diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f8b121c..01496f8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -55,6 +55,7 @@ if(ENABLE_CJSON_TEST) misc_tests parse_with_opts compare_tests + cjson_add ) option(ENABLE_VALGRIND OFF "Enable the valgrind memory checker for the tests.") diff --git a/tests/cjson_add.c b/tests/cjson_add.c new file mode 100644 index 0000000..601d666 --- /dev/null +++ b/tests/cjson_add.c @@ -0,0 +1,145 @@ +/* + Copyright (c) 2009-2017 Dave Gamble and cJSON contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include +#include +#include + +#include "unity/examples/unity_config.h" +#include "unity/src/unity.h" +#include "common.h" + +static void cjson_add_null_should_add_null(void) +{ + cJSON *root = cJSON_CreateObject(); + cJSON *null = NULL; + + cJSON_AddNullToObject(root, "null"); + + TEST_ASSERT_NOT_NULL(null = cJSON_GetObjectItemCaseSensitive(root, "null")); + TEST_ASSERT_EQUAL_INT(null->type, cJSON_NULL); + + cJSON_Delete(root); +} + +static void cjson_add_true_should_add_true(void) +{ + cJSON *root = cJSON_CreateObject(); + cJSON *true_item = NULL; + + cJSON_AddTrueToObject(root, "true"); + + TEST_ASSERT_NOT_NULL(true_item = cJSON_GetObjectItemCaseSensitive(root, "true")); + TEST_ASSERT_EQUAL_INT(true_item->type, cJSON_True); + + cJSON_Delete(root); +} + +static void cjson_add_false_should_add_false(void) +{ + cJSON *root = cJSON_CreateObject(); + cJSON *false_item = NULL; + + cJSON_AddFalseToObject(root, "false"); + + TEST_ASSERT_NOT_NULL(false_item = cJSON_GetObjectItemCaseSensitive(root, "false")); + TEST_ASSERT_EQUAL_INT(false_item->type, cJSON_False); + + cJSON_Delete(root); +} + +static void cjson_add_bool_should_add_bool(void) +{ + cJSON *root = cJSON_CreateObject(); + cJSON *true_item = NULL; + cJSON *false_item = NULL; + + /* true */ + cJSON_AddBoolToObject(root, "true", true); + TEST_ASSERT_NOT_NULL(true_item = cJSON_GetObjectItemCaseSensitive(root, "true")); + TEST_ASSERT_EQUAL_INT(true_item->type, cJSON_True); + + /* false */ + cJSON_AddBoolToObject(root, "false", false); + TEST_ASSERT_NOT_NULL(false_item = cJSON_GetObjectItemCaseSensitive(root, "false")); + TEST_ASSERT_EQUAL_INT(false_item->type, cJSON_False); + + cJSON_Delete(root); +} + +static void cjson_add_number_should_add_number(void) +{ + cJSON *root = cJSON_CreateObject(); + cJSON *number = NULL; + + cJSON_AddNumberToObject(root, "number", 42); + + TEST_ASSERT_NOT_NULL(number = cJSON_GetObjectItemCaseSensitive(root, "number")); + + TEST_ASSERT_EQUAL_INT(number->type, cJSON_Number); + TEST_ASSERT_EQUAL_DOUBLE(number->valuedouble, 42); + TEST_ASSERT_EQUAL_INT(number->valueint, 42); + + cJSON_Delete(root); +} + +static void cjson_add_string_should_add_string(void) +{ + cJSON *root = cJSON_CreateObject(); + cJSON *string = NULL; + + cJSON_AddStringToObject(root, "string", "Hello World!"); + + TEST_ASSERT_NOT_NULL(string = cJSON_GetObjectItemCaseSensitive(root, "string")); + TEST_ASSERT_EQUAL_INT(string->type, cJSON_String); + TEST_ASSERT_EQUAL_STRING(string->valuestring, "Hello World!"); + + cJSON_Delete(root); +} + +static void cjson_add_raw_should_add_raw(void) +{ + cJSON *root = cJSON_CreateObject(); + cJSON *raw = NULL; + + cJSON_AddRawToObject(root, "raw", "{}"); + + TEST_ASSERT_NOT_NULL(raw = cJSON_GetObjectItemCaseSensitive(root, "raw")); + TEST_ASSERT_EQUAL_INT(raw->type, cJSON_Raw); + TEST_ASSERT_EQUAL_STRING(raw->valuestring, "{}"); + + cJSON_Delete(root); +} + +int main(void) +{ + UNITY_BEGIN(); + + RUN_TEST(cjson_add_null_should_add_null); + RUN_TEST(cjson_add_true_should_add_true); + RUN_TEST(cjson_add_false_should_add_false); + RUN_TEST(cjson_add_bool_should_add_bool); + RUN_TEST(cjson_add_number_should_add_number); + RUN_TEST(cjson_add_string_should_add_string); + + return UNITY_END(); +} From 5865faffa371b8334a28fb0d49c9d3ba8f43ced0 Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Thu, 28 Dec 2017 23:56:39 +0100 Subject: [PATCH 4/6] Convert cJSON_Add...ToObject macros into functions These functions return the added object. Functions to add objects and arrays have also been added. --- cJSON.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++ cJSON.h | 16 ++++--- tests/cjson_add.c | 27 ++++++++++++ 3 files changed, 144 insertions(+), 7 deletions(-) diff --git a/cJSON.c b/cJSON.c index 79ce826..e2272e6 100644 --- a/cJSON.c +++ b/cJSON.c @@ -1958,6 +1958,114 @@ CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *str add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false); } +CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name) +{ + cJSON *null = cJSON_CreateNull(); + if (add_item_to_object(object, name, null, &global_hooks, false)) + { + return null; + } + + cJSON_Delete(null); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name) +{ + cJSON *true_item = cJSON_CreateTrue(); + if (add_item_to_object(object, name, true_item, &global_hooks, false)) + { + return true_item; + } + + cJSON_Delete(true_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name) +{ + cJSON *false_item = cJSON_CreateFalse(); + if (add_item_to_object(object, name, false_item, &global_hooks, false)) + { + return false_item; + } + + cJSON_Delete(false_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean) +{ + cJSON *bool_item = cJSON_CreateBool(boolean); + if (add_item_to_object(object, name, bool_item, &global_hooks, false)) + { + return bool_item; + } + + cJSON_Delete(bool_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number) +{ + cJSON *number_item = cJSON_CreateNumber(number); + if (add_item_to_object(object, name, number_item, &global_hooks, false)) + { + return number_item; + } + + cJSON_Delete(number_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string) +{ + cJSON *string_item = cJSON_CreateString(string); + if (add_item_to_object(object, name, string_item, &global_hooks, false)) + { + return string_item; + } + + cJSON_Delete(string_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw) +{ + cJSON *raw_item = cJSON_CreateRaw(raw); + if (add_item_to_object(object, name, raw_item, &global_hooks, false)) + { + return raw_item; + } + + cJSON_Delete(raw_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name) +{ + cJSON *object_item = cJSON_CreateObject(); + if (add_item_to_object(object, name, object_item, &global_hooks, false)) + { + return object_item; + } + + cJSON_Delete(object_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name) +{ + cJSON *array = cJSON_CreateArray(); + if (add_item_to_object(object, name, array, &global_hooks, false)) + { + return array; + } + + cJSON_Delete(array); + return NULL; +} + CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item) { if ((parent == NULL) || (item == NULL)) diff --git a/cJSON.h b/cJSON.h index ba0b258..1734513 100644 --- a/cJSON.h +++ b/cJSON.h @@ -246,13 +246,15 @@ CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * cons CJSON_PUBLIC(void) cJSON_Minify(char *json); /* Macros for creating things quickly. */ -#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull()) -#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue()) -#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse()) -#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b)) -#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n)) -#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) -#define cJSON_AddRawToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateRaw(s)) +CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean); +CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number); +CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string); +CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw); +CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name); /* When assigning an integer value, it needs to be propagated to valuedouble too. */ #define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number)) diff --git a/tests/cjson_add.c b/tests/cjson_add.c index 601d666..03d39ef 100644 --- a/tests/cjson_add.c +++ b/tests/cjson_add.c @@ -130,6 +130,30 @@ static void cjson_add_raw_should_add_raw(void) cJSON_Delete(root); } +static void cJSON_add_object_should_add_object(void) +{ + cJSON *root = cJSON_CreateObject(); + cJSON *object = NULL; + + cJSON_AddObjectToObject(root, "object"); + TEST_ASSERT_NOT_NULL(object = cJSON_GetObjectItemCaseSensitive(root, "object")); + TEST_ASSERT_EQUAL_INT(object->type, cJSON_Object); + + cJSON_Delete(root); +} + +static void cJSON_add_array_should_add_array(void) +{ + cJSON *root = cJSON_CreateObject(); + cJSON *array = NULL; + + cJSON_AddArrayToObject(root, "array"); + TEST_ASSERT_NOT_NULL(array = cJSON_GetObjectItemCaseSensitive(root, "array")); + TEST_ASSERT_EQUAL_INT(array->type, cJSON_Array); + + cJSON_Delete(root); +} + int main(void) { UNITY_BEGIN(); @@ -140,6 +164,9 @@ int main(void) RUN_TEST(cjson_add_bool_should_add_bool); RUN_TEST(cjson_add_number_should_add_number); RUN_TEST(cjson_add_string_should_add_string); + RUN_TEST(cjson_add_raw_should_add_raw); + RUN_TEST(cJSON_add_object_should_add_object); + RUN_TEST(cJSON_add_array_should_add_array); return UNITY_END(); } From 77931e7fc0993c07cb2f4c1ade1aa23b9d01bb51 Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Fri, 29 Dec 2017 23:26:53 +0100 Subject: [PATCH 5/6] cJSON_Add...ToObject: Add tests for failure conditions --- tests/cjson_add.c | 244 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) diff --git a/tests/cjson_add.c b/tests/cjson_add.c index 03d39ef..01668a9 100644 --- a/tests/cjson_add.c +++ b/tests/cjson_add.c @@ -28,6 +28,17 @@ #include "unity/src/unity.h" #include "common.h" +static void *failing_malloc(size_t size) +{ + (void)size; + return NULL; +} + +static cJSON_Hooks failing_hooks = { + failing_malloc, + free +}; + static void cjson_add_null_should_add_null(void) { cJSON *root = cJSON_CreateObject(); @@ -41,6 +52,29 @@ static void cjson_add_null_should_add_null(void) cJSON_Delete(root); } +static void cjson_add_null_should_fail_with_null_pointers(void) +{ + cJSON *root = cJSON_CreateObject(); + + TEST_ASSERT_NULL(cJSON_AddNullToObject(NULL, "null")); + TEST_ASSERT_NULL(cJSON_AddNullToObject(root, NULL)); + + cJSON_Delete(root); +} + +static void cjson_add_null_should_fail_on_allocation_failure(void) +{ + cJSON *root = cJSON_CreateObject(); + + cJSON_InitHooks(&failing_hooks); + + TEST_ASSERT_NULL(cJSON_AddNullToObject(root, "null")); + + cJSON_InitHooks(NULL); + + cJSON_Delete(root); +} + static void cjson_add_true_should_add_true(void) { cJSON *root = cJSON_CreateObject(); @@ -54,6 +88,29 @@ static void cjson_add_true_should_add_true(void) cJSON_Delete(root); } +static void cjson_add_true_should_fail_with_null_pointers(void) +{ + cJSON *root = cJSON_CreateObject(); + + TEST_ASSERT_NULL(cJSON_AddTrueToObject(NULL, "true")); + TEST_ASSERT_NULL(cJSON_AddTrueToObject(root, NULL)); + + cJSON_Delete(root); +} + +static void cjson_add_true_should_fail_on_allocation_failure(void) +{ + cJSON *root = cJSON_CreateObject(); + + cJSON_InitHooks(&failing_hooks); + + TEST_ASSERT_NULL(cJSON_AddTrueToObject(root, "true")); + + cJSON_InitHooks(NULL); + + cJSON_Delete(root); +} + static void cjson_add_false_should_add_false(void) { cJSON *root = cJSON_CreateObject(); @@ -67,6 +124,29 @@ static void cjson_add_false_should_add_false(void) cJSON_Delete(root); } +static void cjson_add_false_should_fail_with_null_pointers(void) +{ + cJSON *root = cJSON_CreateObject(); + + TEST_ASSERT_NULL(cJSON_AddFalseToObject(NULL, "false")); + TEST_ASSERT_NULL(cJSON_AddFalseToObject(root, NULL)); + + cJSON_Delete(root); +} + +static void cjson_add_false_should_fail_on_allocation_failure(void) +{ + cJSON *root = cJSON_CreateObject(); + + cJSON_InitHooks(&failing_hooks); + + TEST_ASSERT_NULL(cJSON_AddFalseToObject(root, "false")); + + cJSON_InitHooks(NULL); + + cJSON_Delete(root); +} + static void cjson_add_bool_should_add_bool(void) { cJSON *root = cJSON_CreateObject(); @@ -86,6 +166,29 @@ static void cjson_add_bool_should_add_bool(void) cJSON_Delete(root); } +static void cjson_add_bool_should_fail_with_null_pointers(void) +{ + cJSON *root = cJSON_CreateObject(); + + TEST_ASSERT_NULL(cJSON_AddBoolToObject(NULL, "false", false)); + TEST_ASSERT_NULL(cJSON_AddBoolToObject(root, NULL, false)); + + cJSON_Delete(root); +} + +static void cjson_add_bool_should_fail_on_allocation_failure(void) +{ + cJSON *root = cJSON_CreateObject(); + + cJSON_InitHooks(&failing_hooks); + + TEST_ASSERT_NULL(cJSON_AddBoolToObject(root, "false", false)); + + cJSON_InitHooks(NULL); + + cJSON_Delete(root); +} + static void cjson_add_number_should_add_number(void) { cJSON *root = cJSON_CreateObject(); @@ -102,6 +205,29 @@ static void cjson_add_number_should_add_number(void) cJSON_Delete(root); } +static void cjson_add_number_should_fail_with_null_pointers(void) +{ + cJSON *root = cJSON_CreateObject(); + + TEST_ASSERT_NULL(cJSON_AddNumberToObject(NULL, "number", 42)); + TEST_ASSERT_NULL(cJSON_AddNumberToObject(root, NULL, 42)); + + cJSON_Delete(root); +} + +static void cjson_add_number_should_fail_on_allocation_failure(void) +{ + cJSON *root = cJSON_CreateObject(); + + cJSON_InitHooks(&failing_hooks); + + TEST_ASSERT_NULL(cJSON_AddNumberToObject(root, "number", 42)); + + cJSON_InitHooks(NULL); + + cJSON_Delete(root); +} + static void cjson_add_string_should_add_string(void) { cJSON *root = cJSON_CreateObject(); @@ -116,6 +242,29 @@ static void cjson_add_string_should_add_string(void) cJSON_Delete(root); } +static void cjson_add_string_should_fail_with_null_pointers(void) +{ + cJSON *root = cJSON_CreateObject(); + + TEST_ASSERT_NULL(cJSON_AddStringToObject(NULL, "string", "string")); + TEST_ASSERT_NULL(cJSON_AddStringToObject(root, NULL, "string")); + + cJSON_Delete(root); +} + +static void cjson_add_string_should_fail_on_allocation_failure(void) +{ + cJSON *root = cJSON_CreateObject(); + + cJSON_InitHooks(&failing_hooks); + + TEST_ASSERT_NULL(cJSON_AddStringToObject(root, "string", "string")); + + cJSON_InitHooks(NULL); + + cJSON_Delete(root); +} + static void cjson_add_raw_should_add_raw(void) { cJSON *root = cJSON_CreateObject(); @@ -130,6 +279,29 @@ static void cjson_add_raw_should_add_raw(void) cJSON_Delete(root); } +static void cjson_add_raw_should_fail_with_null_pointers(void) +{ + cJSON *root = cJSON_CreateObject(); + + TEST_ASSERT_NULL(cJSON_AddRawToObject(NULL, "raw", "{}")); + TEST_ASSERT_NULL(cJSON_AddRawToObject(root, NULL, "{}")); + + cJSON_Delete(root); +} + +static void cjson_add_raw_should_fail_on_allocation_failure(void) +{ + cJSON *root = cJSON_CreateObject(); + + cJSON_InitHooks(&failing_hooks); + + TEST_ASSERT_NULL(cJSON_AddRawToObject(root, "raw", "{}")); + + cJSON_InitHooks(NULL); + + cJSON_Delete(root); +} + static void cJSON_add_object_should_add_object(void) { cJSON *root = cJSON_CreateObject(); @@ -142,6 +314,29 @@ static void cJSON_add_object_should_add_object(void) cJSON_Delete(root); } +static void cjson_add_object_should_fail_with_null_pointers(void) +{ + cJSON *root = cJSON_CreateObject(); + + TEST_ASSERT_NULL(cJSON_AddObjectToObject(NULL, "object")); + TEST_ASSERT_NULL(cJSON_AddObjectToObject(root, NULL)); + + cJSON_Delete(root); +} + +static void cjson_add_object_should_fail_on_allocation_failure(void) +{ + cJSON *root = cJSON_CreateObject(); + + cJSON_InitHooks(&failing_hooks); + + TEST_ASSERT_NULL(cJSON_AddObjectToObject(root, "object")); + + cJSON_InitHooks(NULL); + + cJSON_Delete(root); +} + static void cJSON_add_array_should_add_array(void) { cJSON *root = cJSON_CreateObject(); @@ -154,19 +349,68 @@ static void cJSON_add_array_should_add_array(void) cJSON_Delete(root); } +static void cjson_add_array_should_fail_with_null_pointers(void) +{ + cJSON *root = cJSON_CreateObject(); + + TEST_ASSERT_NULL(cJSON_AddArrayToObject(NULL, "array")); + TEST_ASSERT_NULL(cJSON_AddArrayToObject(root, NULL)); + + cJSON_Delete(root); +} + +static void cjson_add_array_should_fail_on_allocation_failure(void) +{ + cJSON *root = cJSON_CreateObject(); + + cJSON_InitHooks(&failing_hooks); + + TEST_ASSERT_NULL(cJSON_AddArrayToObject(root, "array")); + + cJSON_InitHooks(NULL); + + cJSON_Delete(root); +} + int main(void) { UNITY_BEGIN(); RUN_TEST(cjson_add_null_should_add_null); + RUN_TEST(cjson_add_null_should_fail_with_null_pointers); + RUN_TEST(cjson_add_null_should_fail_on_allocation_failure); + RUN_TEST(cjson_add_true_should_add_true); + RUN_TEST(cjson_add_true_should_fail_with_null_pointers); + RUN_TEST(cjson_add_true_should_fail_on_allocation_failure); + RUN_TEST(cjson_add_false_should_add_false); + RUN_TEST(cjson_add_false_should_fail_with_null_pointers); + RUN_TEST(cjson_add_false_should_fail_on_allocation_failure); + RUN_TEST(cjson_add_bool_should_add_bool); + RUN_TEST(cjson_add_bool_should_fail_with_null_pointers); + RUN_TEST(cjson_add_bool_should_fail_on_allocation_failure); + RUN_TEST(cjson_add_number_should_add_number); + RUN_TEST(cjson_add_number_should_fail_with_null_pointers); + RUN_TEST(cjson_add_number_should_fail_on_allocation_failure); + RUN_TEST(cjson_add_string_should_add_string); + RUN_TEST(cjson_add_string_should_fail_with_null_pointers); + RUN_TEST(cjson_add_string_should_fail_on_allocation_failure); + RUN_TEST(cjson_add_raw_should_add_raw); + RUN_TEST(cjson_add_raw_should_fail_with_null_pointers); + RUN_TEST(cjson_add_raw_should_fail_on_allocation_failure); + RUN_TEST(cJSON_add_object_should_add_object); + RUN_TEST(cjson_add_object_should_fail_with_null_pointers); + RUN_TEST(cjson_add_object_should_fail_on_allocation_failure); + RUN_TEST(cJSON_add_array_should_add_array); + RUN_TEST(cjson_add_array_should_fail_with_null_pointers); + RUN_TEST(cjson_add_array_should_fail_on_allocation_failure); return UNITY_END(); } From 1b21bcd150145ac83351a159d82e4f712ac544b7 Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Fri, 29 Dec 2017 23:29:09 +0100 Subject: [PATCH 6/6] cJSON_Add..ToObject: Add comment to header file --- cJSON.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cJSON.h b/cJSON.h index 1734513..c3d8c76 100644 --- a/cJSON.h +++ b/cJSON.h @@ -245,7 +245,8 @@ CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * cons CJSON_PUBLIC(void) cJSON_Minify(char *json); -/* Macros for creating things quickly. */ +/* Helper functions for creating and adding items to an object at the same time. + * They return the added item or NULL on failure. */ CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name); CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name); CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);