From d23d944f129e260c71d795630a6f23a0c2278d02 Mon Sep 17 00:00:00 2001 From: jef Date: Sat, 27 Oct 2012 16:43:04 -0700 Subject: [PATCH] Fix JSON parsing to handle very long ints better. Should still do something better about them on output. --- src/cjson.c | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/src/cjson.c b/src/cjson.c index bc166c8..f75407d 100644 --- a/src/cjson.c +++ b/src/cjson.c @@ -132,51 +132,65 @@ static double ipow( double n, int exp ) /* 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; + long long i = 0; + double f = 0; + int isint = 1; int sign = 1, scale = 0, subscale = 0, signsubscale = 1; /* Could use sscanf for this? */ if ( *num == '-' ) { /* Has sign. */ sign = -1; - num++; + ++num; } if ( *num == '0' ) /* Is zero. */ - num++; + ++num; if ( *num >= '1' && *num<='9' ) { /* Number. */ do { - n = ( n * 10.0 ) + ( *num++ - '0' ); + i = ( i * 10 ) + ( *num - '0' ); + f = ( f * 10.0 ) + ( *num - '0' ); + ++num; } while ( *num >= '0' && *num <= '9' ); } if ( *num == '.' && num[1] >= '0' && num[1] <= '9' ) { /* Fractional part. */ - num++; + isint = 0; + ++num; do { - n = ( n * 10.0 ) + ( *num++ - '0' ); + f = ( f * 10.0 ) + ( *num++ - '0' ); scale--; } while ( *num >= '0' && *num <= '9' ); } if ( *num == 'e' || *num == 'E' ) { /* Exponent. */ - num++; + isint = 0; + ++num; if ( *num == '+' ) - num++; + ++num; else if ( *num == '-' ) { /* With sign. */ signsubscale = -1; - num++; + ++num; } while ( *num >= '0' && *num <= '9' ) subscale = ( subscale * 10 ) + ( *num++ - '0' ); } - /* Put it together: number = +/- number.fraction * 10^+/- exponent */ - n = sign * n * ipow( 10.0, scale + subscale * signsubscale ); - - item->valuefloat = n; - item->valueint = n; + /* Put it together. */ + if ( isint ) { + /* Int: number = +/- number */ + i = sign * i; + item->valueint = i; + item->valuefloat = i; + } else { + /* Float: number = +/- number.fraction * 10^+/- exponent */ + f = sign * f * ipow( 10.0, scale + subscale * signsubscale ); + item->valueint = f; + item->valuefloat = f; + } + item->type = cJSON_Number; return num; }