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

An 'outside the range of int' bug found in cJSON_CreateNumber #806

Open
PromptFuzz opened this issue Dec 6, 2023 · 2 comments
Open

An 'outside the range of int' bug found in cJSON_CreateNumber #806

PromptFuzz opened this issue Dec 6, 2023 · 2 comments

Comments

@PromptFuzz
Copy link

Hi,
UBSAN reported an error in cJSON_CreateNumber.

/cjson/src/cjson/cJSON.c:2448:30: runtime error: nan is outside the range of representable values of type 'int'
   #0 0x55ab38f2da64 in cJSON_CreateNumber /cjson/src/cjson/cJSON.c:2448:30
   #1 0x55ab38f2d64c in cJSON_AddNumberToObject /cjson/src/cjson/cJSON.c:2129:26
   #2 0x55ab38f1f0d1 in LLVMFuzzerTestOneInput /poc.cc:42:13

PoC
poc.tar.gz

@PeterAlfredLee
Copy link
Contributor

You are reading a string value using cJSON_GetNumberValue, which will return a NAN(link).

It's designed to be like this. I don't think this is an error.

@daschfg
Copy link

daschfg commented Dec 17, 2023

For easier reference, a boiled down POC:

const char* input = "{ \"Width\": \"100\" }";
cJSON* root = cJSON_Parse(input);

cJSON* widthObj = cJSON_GetObjectItem(root, "Width");
double width = cJSON_GetNumberValue(widthObj);  // Trying to read a string object as number value

printf("%f\n", width);                          // width == NAN

cJSON_AddNumberToObject(root, "Width2", width); // UBSAN reports error here

I agree, this looks like expected behaviour.

But the runtime error seems to be explicitly about the cast to int in cJSON_CreateNumber, which is necessary for the assignment to valueint.
From what I understand, casting NAN to integer should be undefined behaviour with C89.

Overall this would be another argument for future versions to drop valueint completely, as discussed for example in #63

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

3 participants