Skip to content

Commit

Permalink
Merge pull request #453 from Alanscut/add-return-value
Browse files Browse the repository at this point in the history
add return value for  cJSON_AddItemTo... and cJSON_ReplaceItemxxx
  • Loading branch information
Alanscut authored Apr 2, 2020
2 parents f12cd7b + af56a14 commit 65578af
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 48 deletions.
54 changes: 26 additions & 28 deletions cJSON.c
Original file line number Diff line number Diff line change
Expand Up @@ -1929,7 +1929,7 @@ static cJSON_bool add_item_to_array(cJSON *array, cJSON *item)
{
cJSON *child = NULL;

if ((item == NULL) || (array == NULL))
if ((item == NULL) || (array == NULL) || (array == item))
{
return false;
}
Expand Down Expand Up @@ -1968,9 +1968,9 @@ static cJSON_bool add_item_to_array(cJSON *array, cJSON *item)
}

/* Add item to array/object. */
CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item)
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item)
{
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))))
Expand All @@ -1994,7 +1994,7 @@ static cJSON_bool add_item_to_object(cJSON * const object, const char * const st
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;
}
Expand Down Expand Up @@ -2026,35 +2026,35 @@ static cJSON_bool add_item_to_object(cJSON * const object, const char * const st
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)
{
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 */
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)
{
add_item_to_object(object, string, item, &global_hooks, true);
return add_item_to_object(object, string, item, &global_hooks, true);
}

CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)
{
if (array == NULL)
{
return;
return false;
}

add_item_to_array(array, create_reference(item, &global_hooks));
return add_item_to_array(array, create_reference(item, &global_hooks));
}

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))
{
return;
return false;
}

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)
Expand Down Expand Up @@ -2235,20 +2235,19 @@ CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const
}

/* 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)
{
return;
return false;
}

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;
Expand All @@ -2262,6 +2261,7 @@ CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newit
{
newitem->prev->next = newitem;
}
return true;
}

CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement)
Expand Down Expand Up @@ -2305,14 +2305,14 @@ CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON
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)
{
return;
return false;
}

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)
Expand All @@ -2330,19 +2330,17 @@ static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSO
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);
}

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)
{
replace_item_in_object(object, string, newitem, false);
return replace_item_in_object(object, string, newitem, false);
}

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)
{
replace_item_in_object(object, string, newitem, true);
return replace_item_in_object(object, string, newitem, true);
}

/* Create basic types: */
Expand Down
18 changes: 9 additions & 9 deletions cJSON.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,15 +224,15 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
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` */
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. */
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);
Expand All @@ -244,11 +244,11 @@ CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string)
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);
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);
Expand Down
41 changes: 30 additions & 11 deletions tests/misc_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,13 +332,15 @@ static void cjson_replace_item_in_object_should_preserve_name(void)
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);

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);
Expand Down Expand Up @@ -410,19 +412,19 @@ static void cjson_functions_should_not_crash_with_null_pointers(void)
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));
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));
Expand Down Expand Up @@ -544,6 +546,22 @@ static void cjson_create_array_reference_should_create_an_array_reference(void)
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();
Expand Down Expand Up @@ -657,6 +675,7 @@ int CJSON_CDECL main(void)
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);
Expand Down

0 comments on commit 65578af

Please sign in to comment.