(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