Skip to content

Call to cJSONUtils_SortObject() could break adding new fields to the object/array #904

Open
@vdcow

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.

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions