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 · 4 comments · May be fixed by #908
Open

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

vdcow opened this issue Nov 15, 2024 · 4 comments · May be fixed by #908

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.

@nathanjjohnson7
Copy link

@vdcow, if you ever find the time, I'd love to know if my pull request solved the issue for you.

@vdcow
Copy link
Author

vdcow commented Dec 17, 2024

@nathanjjohnson7 Yep, your fix resolves the issue. Thank you!

@nathanjjohnson7
Copy link

@vdcow Perfect! Thanks for letting me know!

@nathanjjohnson7
Copy link

@Alanscut @PeterAlfredLee I'd appreciate it if you could look into this. It seems to fix the issue. Thanks!

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