浏览代码

fix #174: cJSON_ReplaceItemInObject doesn't copy name

Max Bruckner 8 年之前
父节点
当前提交
9ecc96878f
共有 2 个文件被更改,包括 43 次插入2 次删除
  1. 22 2
      cJSON.c
  2. 21 0
      tests/misc_tests.c

+ 22 - 2
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: */

+ 21 - 0
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();
 }