(SYSTEM: ArchLinux - current version, gpgme version 1.12.0)
Problem:
runtime error: signed integer overflow: 2147483640 + 8 cannot be represented in type 'int'
if
const char * num
is a very large number, then the variable subscale will overflow
while (*num >= '0' && *num <= '9'){
subscale = (subscale * 10) + (*num++ - '0'); /* Number? */
}Example:
{
"name": "123e11235135987",
}The exponent integer is larger then the representation of an integer value
FIX:
/* Parse the input text to generate a number, and populate the result
* into item. */
static const char *
parse_number (cJSON * item, const char *num)
{
double n = 0, sign = 1, scale = 0;
int subscale = 0, signsubscale = 1;
if (*num == '-')
sign = -1, num++; /* Has sign? */
if (*num == '0')
num++; /* is zero */
if (*num >= '1' && *num <= '9')
do
n = (n * 10.0) + (*num++ - '0');
while (*num >= '0' && *num <= '9'); /* Number? */
if (*num == '.' && num[1] >= '0' && num[1] <= '9')
{
num++;
do
n = (n * 10.0) + (*num++ - '0'), scale--;
while (*num >= '0' && *num <= '9');
} /* Fractional part? */
if (*num == 'e' || *num == 'E') /* Exponent? */
{
num++;
if (*num == '+')
num++;
else if (*num == '-')
signsubscale = -1, num++; /* With sign? */
while (*num >= '0' && *num <= '9'){
double tmp = ((double) subscale)*10;
double max_value = INT32_MAX;
if(tmp > max_value){
break;
}else{
subscale = (subscale * 10) + (*num++ - '0'); /* Number? */
}
}
}
/* number = +/- number.fraction * 10^+/- exponent */
n = sign * n * pow (10.0, (scale + subscale * signsubscale));
// proof if n is "nan" or "inf"
if( isnan(n) || isinf(n) ) {
item->valuedouble = 0;
item->valueint = 0;
} else {
double max_value = INT32_MAX;
double min_value = INT32_MIN;
if(n > max_value){
item->valueint = 0;
item->valuedouble = n;
} else if(n < min_value) {
item->valueint = 0;
item->valuedouble = n;
} else {
item->valuedouble = n;
item->valueint = (int) n;
}
}
item->type = cJSON_Number;
return num;
}found with libFuzzer and ASAN by clang 7.0.1
regards
Sirko Höer
Code Intelligence GmbH