Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
vdcow opened this issue Nov 15, 2024 · 0 comments

Comments

@vdcow
Copy link

vdcow commented Nov 15, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant