Call to cJSONUtils_SortObject() could break adding new fields to the object/array #904
Description
I have found that cJSONUtils_SortObject(object) call if "object" is unsorted could break adding new fields to the object/array. It happens when the last field in the unsorted array/object becomes the first field.
In this case sorted object will have "object->child->prev" equal to 0 breaking the following assumption in the code
https://github.com/DaveGamble/cJSON/blob/master/cJSON.c#L2008
/* append to the end */
if (child->prev) <--------------------------- will be zero for sorted object
{
suffix_object(child->prev, item);
array->child->prev = item;
}
Another bad thing is that in this case we also have a memory leak since "item" variable is not assigned anywhere.
Moreover any API call from cJSON_Utils that is using sort_object() call internally also could break the input object. I am personally found it when debugging cJSONUtils_ApplyPatches().
Minimal example that reproduces the problem
#include <stdlib.h>
#include <stdio.h>
#include <cJSON.h>
#include <cJSON_Utils.h>
int main() {
cJSON *object = cJSON_Parse(
"{\"v1\": 1, \"a2\": 2}");
char *object_str = cJSON_Print(object);
printf("object=\n%s\n", object_str);
free(object_str);
cJSONUtils_SortObject(object);
cJSON *v3_value = cJSON_CreateNumber(3);
cJSON_AddItemToObject(object, "v3", v3_value);
object_str = cJSON_Print(object);
printf("object=\n%s\n", object_str);
free(object_str);
return 0;
}
Output of the program is
object=
{
"v1": 1,
"a2": 2
}
object=
{
"a2": 2,
"v1": 1
}
Note that "v3" field is missed in the final JSON.