cJSON
cJSON copied to clipboard
An 'outside the range of int' bug found in cJSON_CreateNumber
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
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.
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