diff --git a/cJSON.c b/cJSON.c index c50c8ec..58e5c98 100644 --- a/cJSON.c +++ b/cJSON.c @@ -1975,14 +1975,34 @@ CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newi 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) +{ + if (replacement == NULL) + { + return false; + } + + /* replace the name in the replacement */ + if (!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL)) + { + cJSON_free(replacement->string); + } + 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; +} + CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) { - cJSON_ReplaceItemViaPointer(object, cJSON_GetObjectItem(object, string), newitem); + replace_item_in_object(object, string, newitem, false); } CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem) { - cJSON_ReplaceItemViaPointer(object, cJSON_GetObjectItemCaseSensitive(object, string), newitem); + replace_item_in_object(object, string, newitem, true); } /* Create basic types: */ diff --git a/tests/misc_tests.c b/tests/misc_tests.c index 24a390d..9619db2 100644 --- a/tests/misc_tests.c +++ b/tests/misc_tests.c @@ -304,6 +304,26 @@ static void cjson_replace_item_via_pointer_should_replace_items(void) cJSON_free(array); } +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; + + child = cJSON_CreateNumber(1); + TEST_ASSERT_NOT_NULL(child); + replacement = cJSON_CreateNumber(2); + TEST_ASSERT_NOT_NULL(replacement); + + cJSON_AddItemToObject(root, "child", child); + cJSON_ReplaceItemInObject(root, "child", replacement); + + TEST_ASSERT_TRUE(root->child == replacement); + TEST_ASSERT_EQUAL_STRING("child", replacement->string); + + cJSON_Delete(replacement); +} + int main(void) { UNITY_BEGIN(); @@ -317,6 +337,7 @@ int main(void) RUN_TEST(cjson_set_number_value_should_set_numbers); RUN_TEST(cjson_detach_item_via_pointer_should_detach_items); RUN_TEST(cjson_replace_item_via_pointer_should_replace_items); + RUN_TEST(cjson_replace_item_in_object_should_preserve_name); return UNITY_END(); }