cJSON icon indicating copy to clipboard operation
cJSON copied to clipboard

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

Open PromptFuzz opened this issue 1 year ago • 2 comments

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

PromptFuzz avatar Dec 06 '23 05:12 PromptFuzz

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.

PeterAlfredLee avatar Dec 16 '23 07:12 PeterAlfredLee

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 https://github.com/DaveGamble/cJSON/issues/63

daschfg avatar Dec 17 '23 00:12 daschfg