diff --git a/cJSON.c b/cJSON.c index fa2e2fd37d5d67ee6998a40dbd12462b2783a407_Y0pTT04uYw==..d9348c932dad345a277fa4404b4d7dc779b186d0_Y0pTT04uYw== 100644 --- a/cJSON.c +++ b/cJSON.c @@ -1929,7 +1929,7 @@ { cJSON *child = NULL; - if ((item == NULL) || (array == NULL)) + if ((item == NULL) || (array == NULL) || (array == item)) { return false; } @@ -1968,5 +1968,5 @@ } /* Add item to array/object. */ -CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item) +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item) { @@ -1972,5 +1972,5 @@ { - add_item_to_array(array, item); + return add_item_to_array(array, item); } #if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) @@ -1994,7 +1994,7 @@ char *new_key = NULL; int new_type = cJSON_Invalid; - if ((object == NULL) || (string == NULL) || (item == NULL)) + if ((object == NULL) || (string == NULL) || (item == NULL) || (object == item)) { return false; } @@ -2026,5 +2026,5 @@ return add_item_to_array(object, item); } -CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) { @@ -2030,5 +2030,5 @@ { - add_item_to_object(object, string, item, &global_hooks, false); + return add_item_to_object(object, string, item, &global_hooks, false); } /* Add an item to an object with constant string as key */ @@ -2032,5 +2032,5 @@ } /* Add an item to an object with constant string as key */ -CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item) +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item) { @@ -2036,4 +2036,4 @@ { - add_item_to_object(object, string, item, &global_hooks, true); + return add_item_to_object(object, string, item, &global_hooks, true); } @@ -2038,6 +2038,6 @@ } -CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) { if (array == NULL) { @@ -2041,6 +2041,6 @@ { if (array == NULL) { - return; + return false; } @@ -2045,5 +2045,5 @@ } - add_item_to_array(array, create_reference(item, &global_hooks)); + return add_item_to_array(array, create_reference(item, &global_hooks)); } @@ -2048,6 +2048,6 @@ } -CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item) +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item) { if ((object == NULL) || (string == NULL)) { @@ -2051,6 +2051,6 @@ { if ((object == NULL) || (string == NULL)) { - return; + return false; } @@ -2055,6 +2055,6 @@ } - add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false); + return 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) @@ -2235,9 +2235,9 @@ } /* Replace array/object items with new ones. */ -CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem) +CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem) { cJSON *after_inserted = NULL; if (which < 0) { @@ -2239,11 +2239,11 @@ { cJSON *after_inserted = NULL; if (which < 0) { - return; + return false; } after_inserted = get_array_item(array, (size_t)which); if (after_inserted == NULL) { @@ -2245,10 +2245,9 @@ } after_inserted = get_array_item(array, (size_t)which); if (after_inserted == NULL) { - add_item_to_array(array, newitem); - return; + return add_item_to_array(array, newitem); } newitem->next = after_inserted; @@ -2262,6 +2261,7 @@ { newitem->prev->next = newitem; } + return true; } CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement) @@ -2305,7 +2305,7 @@ return true; } -CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) { if (which < 0) { @@ -2309,6 +2309,6 @@ { if (which < 0) { - return; + return false; } @@ -2313,6 +2313,6 @@ } - cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem); + return cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem); } static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive) @@ -2330,8 +2330,6 @@ replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); replacement->type &= ~cJSON_StringIsConst; - cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement); - - return true; + return cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement); } @@ -2336,4 +2334,4 @@ } -CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) { @@ -2339,4 +2337,4 @@ { - replace_item_in_object(object, string, newitem, false); + return replace_item_in_object(object, string, newitem, false); } @@ -2341,4 +2339,4 @@ } -CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem) +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem) { @@ -2344,5 +2342,5 @@ { - replace_item_in_object(object, string, newitem, true); + return replace_item_in_object(object, string, newitem, true); } /* Create basic types: */ diff --git a/cJSON.h b/cJSON.h index fa2e2fd37d5d67ee6998a40dbd12462b2783a407_Y0pTT04uaA==..d9348c932dad345a277fa4404b4d7dc779b186d0_Y0pTT04uaA== 100644 --- a/cJSON.h +++ b/cJSON.h @@ -224,8 +224,8 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count); /* Append item to the specified array/object. */ -CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item); -CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); /* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object. * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before * writing to `item->string` */ @@ -229,5 +229,5 @@ /* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object. * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before * writing to `item->string` */ -CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item); +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item); /* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ @@ -233,6 +233,6 @@ /* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ -CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); -CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item); +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item); /* Remove/Detach items from Arrays/Objects. */ CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item); @@ -244,5 +244,5 @@ CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string); /* Update array items. */ -CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */ +CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */ CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement); @@ -248,7 +248,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement); -CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem); -CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); -CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem); +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem); +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem); /* Duplicate a cJSON item */ CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse); diff --git a/tests/misc_tests.c b/tests/misc_tests.c index fa2e2fd37d5d67ee6998a40dbd12462b2783a407_dGVzdHMvbWlzY190ZXN0cy5j..d9348c932dad345a277fa4404b4d7dc779b186d0_dGVzdHMvbWlzY190ZXN0cy5j 100644 --- a/tests/misc_tests.c +++ b/tests/misc_tests.c @@ -332,9 +332,10 @@ cJSON root[1] = {{ NULL, NULL, NULL, 0, NULL, 0, 0, NULL }}; cJSON *child = NULL; cJSON *replacement = NULL; + cJSON_bool flag = false; child = cJSON_CreateNumber(1); TEST_ASSERT_NOT_NULL(child); replacement = cJSON_CreateNumber(2); TEST_ASSERT_NOT_NULL(replacement); @@ -335,10 +336,11 @@ child = cJSON_CreateNumber(1); TEST_ASSERT_NOT_NULL(child); replacement = cJSON_CreateNumber(2); TEST_ASSERT_NOT_NULL(replacement); - cJSON_AddItemToObject(root, "child", child); + flag = cJSON_AddItemToObject(root, "child", child); + TEST_ASSERT_TRUE_MESSAGE(flag, "add item to object failed"); cJSON_ReplaceItemInObject(root, "child", replacement); TEST_ASSERT_TRUE(root->child == replacement); @@ -410,8 +412,8 @@ cJSON_DeleteItemFromObject(item, NULL); cJSON_DeleteItemFromObjectCaseSensitive(NULL, "item"); cJSON_DeleteItemFromObjectCaseSensitive(item, NULL); - cJSON_InsertItemInArray(NULL, 0, item); - cJSON_InsertItemInArray(item, 0, NULL); + TEST_ASSERT_FALSE(cJSON_InsertItemInArray(NULL, 0, item)); + TEST_ASSERT_FALSE(cJSON_InsertItemInArray(item, 0, NULL)); TEST_ASSERT_FALSE(cJSON_ReplaceItemViaPointer(NULL, item, item)); TEST_ASSERT_FALSE(cJSON_ReplaceItemViaPointer(item, NULL, item)); TEST_ASSERT_FALSE(cJSON_ReplaceItemViaPointer(item, item, NULL)); @@ -415,14 +417,14 @@ TEST_ASSERT_FALSE(cJSON_ReplaceItemViaPointer(NULL, item, item)); TEST_ASSERT_FALSE(cJSON_ReplaceItemViaPointer(item, NULL, item)); TEST_ASSERT_FALSE(cJSON_ReplaceItemViaPointer(item, item, NULL)); - cJSON_ReplaceItemInArray(item, 0, NULL); - cJSON_ReplaceItemInArray(NULL, 0, item); - cJSON_ReplaceItemInObject(NULL, "item", item); - cJSON_ReplaceItemInObject(item, NULL, item); - cJSON_ReplaceItemInObject(item, "item", NULL); - cJSON_ReplaceItemInObjectCaseSensitive(NULL, "item", item); - cJSON_ReplaceItemInObjectCaseSensitive(item, NULL, item); - cJSON_ReplaceItemInObjectCaseSensitive(item, "item", NULL); + TEST_ASSERT_FALSE(cJSON_ReplaceItemInArray(item, 0, NULL)); + TEST_ASSERT_FALSE(cJSON_ReplaceItemInArray(NULL, 0, item)); + TEST_ASSERT_FALSE(cJSON_ReplaceItemInObject(NULL, "item", item)); + TEST_ASSERT_FALSE(cJSON_ReplaceItemInObject(item, NULL, item)); + TEST_ASSERT_FALSE(cJSON_ReplaceItemInObject(item, "item", NULL)); + TEST_ASSERT_FALSE(cJSON_ReplaceItemInObjectCaseSensitive(NULL, "item", item)); + TEST_ASSERT_FALSE(cJSON_ReplaceItemInObjectCaseSensitive(item, NULL, item)); + TEST_ASSERT_FALSE(cJSON_ReplaceItemInObjectCaseSensitive(item, "item", NULL)); TEST_ASSERT_NULL(cJSON_Duplicate(NULL, true)); TEST_ASSERT_FALSE(cJSON_Compare(item, NULL, false)); TEST_ASSERT_FALSE(cJSON_Compare(NULL, item, false)); @@ -544,6 +546,22 @@ cJSON_Delete(number_reference); } +static void cjson_add_item_to_object_or_array_should_not_add_itself(void) +{ + cJSON *object = cJSON_CreateObject(); + cJSON *array = cJSON_CreateArray(); + cJSON_bool flag = false; + + flag = cJSON_AddItemToObject(object, "key", object); + TEST_ASSERT_FALSE_MESSAGE(flag, "add an object to itself should fail"); + + flag = cJSON_AddItemToArray(array, array); + TEST_ASSERT_FALSE_MESSAGE(flag, "add an array to itself should fail"); + + cJSON_Delete(object); + cJSON_Delete(array); +} + static void cjson_add_item_to_object_should_not_use_after_free_when_string_is_aliased(void) { cJSON *object = cJSON_CreateObject(); @@ -657,6 +675,7 @@ RUN_TEST(cjson_create_string_reference_should_create_a_string_reference); RUN_TEST(cjson_create_object_reference_should_create_an_object_reference); RUN_TEST(cjson_create_array_reference_should_create_an_array_reference); + RUN_TEST(cjson_add_item_to_object_or_array_should_not_add_itself); RUN_TEST(cjson_add_item_to_object_should_not_use_after_free_when_string_is_aliased); RUN_TEST(cjson_delete_item_from_array_should_not_broken_list_structure); RUN_TEST(cjson_set_valuestring_to_object_should_not_leak_memory);