summaryrefslogtreecommitdiff
path: root/src/cJSON.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cJSON.c')
-rw-r--r--src/cJSON.c48
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);