diff --git a/cJSON.c b/cJSON.c index bc95cde..a198d66 100644 --- a/cJSON.c +++ b/cJSON.c @@ -1871,22 +1871,34 @@ static cJSON_bool add_item_to_array(cJSON *array, cJSON *item) } child = array->child; - + /* + * To find the last item int array quickly, we use prev in array + */ if (child == NULL) { /* list is empty, start new one */ array->child = item; + item->prev = item; + item->next = NULL; } else { /* append to the end */ - while (child->next) + if (child->prev) { - child = child->next; + suffix_object(child->prev, item); + array->child->prev = item; + } + else + { + while (child->next) + { + child = child->next; + } + suffix_object(child, item); + array->child->prev = item; } - suffix_object(child, item); } - return true; } @@ -2206,14 +2218,21 @@ CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON { replacement->next->prev = replacement; } - if (replacement->prev != NULL) - { - replacement->prev->next = replacement; - } + if (parent->child == item) { parent->child = replacement; } + else + { /* + * To find the last item int array quickly, we use prev in array. + * We can't modify the last item's next pointer where this item was the parent's child + */ + if (replacement->prev != NULL) + { + replacement->prev->next = replacement; + } + } item->next = NULL; item->prev = NULL; diff --git a/tests/misc_tests.c b/tests/misc_tests.c index 1635fa3..9551683 100644 --- a/tests/misc_tests.c +++ b/tests/misc_tests.c @@ -306,7 +306,7 @@ static void cjson_replace_item_via_pointer_should_replace_items(void) /* replace beginning */ TEST_ASSERT_TRUE(cJSON_ReplaceItemViaPointer(array, beginning, &(replacements[0]))); - TEST_ASSERT_NULL(replacements[0].prev); + TEST_ASSERT_TRUE(replacements[0].prev == end); TEST_ASSERT_TRUE(replacements[0].next == middle); TEST_ASSERT_TRUE(middle->prev == &(replacements[0])); TEST_ASSERT_TRUE(array->child == &(replacements[0]));