diff options
Diffstat (limited to 'src/cJSON.c')
-rw-r--r-- | src/cJSON.c | 48 |
1 files changed, 40 insertions, 8 deletions
diff --git a/src/cJSON.c b/src/cJSON.c index 101d556..f233848 100644 --- a/src/cJSON.c +++ b/src/cJSON.c @@ -40,6 +40,7 @@ #include <stdio.h> #include <math.h> #include <stdlib.h> +#include <stdint.h> #include <float.h> #include <limits.h> #include <ctype.h> @@ -146,8 +147,13 @@ cJSON_Delete (cJSON * c) static const char * parse_number (cJSON * item, const char *num) { - double n = 0, sign = 1, scale = 0; - int subscale = 0, signsubscale = 1; + int subscale = 0; + int signsubscale = 1; + double n = 0; + double sign = 1; + double scale = 0; + double dblmin = INT32_MIN; + double dblmax = INT32_MAX; if (*num == '-') sign = -1, num++; /* Has sign? */ @@ -169,17 +175,37 @@ parse_number (cJSON * item, const char *num) num++; if (*num == '+') num++; - else if (*num == '-') - signsubscale = -1, num++; /* With sign? */ + else if (*num == '-') /* With sign? */ + signsubscale = -1, num++; while (*num >= '0' && *num <= '9') - subscale = (subscale * 10) + (*num++ - '0'); /* Number? */ + { + if ((10 * (double)subscale) > dblmax) + break; + subscale = (subscale * 10) + (*num++ - '0'); + } } /* number = +/- number.fraction * 10^+/- exponent */ n = sign * n * pow (10.0, (scale + subscale * signsubscale)); - item->valuedouble = n; - item->valueint = (int) n; + /* For NAN set both parts to 0. For out of range values let the + * integer part be 0. */ + if (isnan (n) || isinf (n)) + { + item->valuedouble = 0; + item->valueint = 0; + } + else if (n > dblmax || n < dblmin) + { + item->valuedouble = n; + item->valueint = 0; + } + else + { + item->valuedouble = n; + item->valueint = (int)n; + } + item->type = cJSON_Number; return num; } @@ -190,6 +216,8 @@ print_number (cJSON * item) { char *str; double d = item->valuedouble; + int i; + if (fabs (((double) item->valueint) - d) <= DBL_EPSILON && d <= INT_MAX && d >= INT_MIN) { @@ -203,7 +231,11 @@ print_number (cJSON * item) str = xtrymalloc (64); /* This is a nice tradeoff. */ if (str) { - if (fabs (floor (d) - d) <= DBL_EPSILON && fabs (d) < 1.0e60) + if (isnan (d)) + strcpy (str, "nan"); + else if ((i = isinf (d))) + strcpy (str, i > 0? "inf" : ":-inf"); + else if (fabs (floor (d) - d) <= DBL_EPSILON && fabs (d) < 1.0e60) sprintf (str, "%.0f", d); else if (fabs (d) < 1.0e-6 || fabs (d) > 1.0e9) sprintf (str, "%e", d); |