|
|
@@ -57,7 +57,8 @@ |
|
|
|
static const char json_null_str[] = "null"; |
|
|
|
static const int json_null_str_len = sizeof(json_null_str) - 1; |
|
|
|
static const char json_inf_str[] = "Infinity"; |
|
|
|
static const int json_inf_str_len = sizeof(json_inf_str) - 1; |
|
|
|
static const char json_inf_str_lower[] = "infinity"; |
|
|
|
static const unsigned int json_inf_str_len = sizeof(json_inf_str) - 1; |
|
|
|
static const char json_nan_str[] = "NaN"; |
|
|
|
static const int json_nan_str_len = sizeof(json_nan_str) - 1; |
|
|
|
static const char json_true_str[] = "true"; |
|
|
@@ -383,40 +384,55 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok, |
|
|
|
tok->depth--; |
|
|
|
goto redo_char; |
|
|
|
|
|
|
|
case json_tokener_state_inf: /* aka starts with 'i' */ |
|
|
|
case json_tokener_state_inf: /* aka starts with 'i' (or 'I', or "-i", or "-I") */ |
|
|
|
{ |
|
|
|
size_t size_inf; |
|
|
|
/* If we were guaranteed to have len set, then we could (usually) handle |
|
|
|
* the entire "Infinity" check in a single strncmp (strncasecmp), but |
|
|
|
* since len might be -1 (i.e. "read until \0"), we need to check it |
|
|
|
* a character at a time. |
|
|
|
* Trying to handle it both ways would make this code considerably more |
|
|
|
* complicated with likely little performance benefit. |
|
|
|
*/ |
|
|
|
int is_negative = 0; |
|
|
|
char *infbuf; |
|
|
|
const char *_json_inf_str = json_inf_str; |
|
|
|
if (!(tok->flags & JSON_TOKENER_STRICT)) |
|
|
|
_json_inf_str = json_inf_str_lower; |
|
|
|
|
|
|
|
printbuf_memappend_fast(tok->pb, &c, 1); |
|
|
|
size_inf = json_min(tok->st_pos+1, json_inf_str_len); |
|
|
|
infbuf = tok->pb->buf; |
|
|
|
if (*infbuf == '-') |
|
|
|
{ |
|
|
|
infbuf++; |
|
|
|
is_negative = 1; |
|
|
|
} |
|
|
|
if ((!(tok->flags & JSON_TOKENER_STRICT) && |
|
|
|
strncasecmp(json_inf_str, infbuf, size_inf) == 0) || |
|
|
|
(strncmp(json_inf_str, infbuf, size_inf) == 0) |
|
|
|
) |
|
|
|
/* Note: tok->st_pos must be 0 when state is set to json_tokener_state_inf */ |
|
|
|
while (tok->st_pos < (int)json_inf_str_len) |
|
|
|
{ |
|
|
|
if (tok->st_pos == json_inf_str_len) |
|
|
|
char inf_char = *str; |
|
|
|
if (!(tok->flags & JSON_TOKENER_STRICT)) |
|
|
|
inf_char = tolower(*str); |
|
|
|
if (inf_char != _json_inf_str[tok->st_pos]) |
|
|
|
{ |
|
|
|
current = json_object_new_double(is_negative |
|
|
|
? -INFINITY : INFINITY); |
|
|
|
if(current == NULL) |
|
|
|
goto out; |
|
|
|
saved_state = json_tokener_state_finish; |
|
|
|
state = json_tokener_state_eatws; |
|
|
|
goto redo_char; |
|
|
|
tok->err = json_tokener_error_parse_unexpected; |
|
|
|
goto out; |
|
|
|
} |
|
|
|
tok->st_pos++; |
|
|
|
(void)ADVANCE_CHAR(str, tok); |
|
|
|
if (!PEEK_CHAR(c, tok)) |
|
|
|
{ |
|
|
|
/* out of input chars, for now at least */ |
|
|
|
goto out; |
|
|
|
} |
|
|
|
} else { |
|
|
|
tok->err = json_tokener_error_parse_unexpected; |
|
|
|
goto out; |
|
|
|
} |
|
|
|
tok->st_pos++; |
|
|
|
/* We checked the full length of "Infinity", so create the object. |
|
|
|
* When handling -Infinity, the number parsing code will have dropped |
|
|
|
* the "-" into tok->pb for us, so check it now. |
|
|
|
*/ |
|
|
|
if (printbuf_length(tok->pb) > 0 && *(tok->pb->buf) == '-') |
|
|
|
{ |
|
|
|
is_negative = 1; |
|
|
|
} |
|
|
|
current = json_object_new_double(is_negative |
|
|
|
? -INFINITY : INFINITY); |
|
|
|
if (current == NULL) |
|
|
|
goto out; |
|
|
|
saved_state = json_tokener_state_finish; |
|
|
|
state = json_tokener_state_eatws; |
|
|
|
goto redo_char; |
|
|
|
|
|
|
|
} |
|
|
|
break; |
|
|
|
case json_tokener_state_null: /* aka starts with 'n' */ |
|
|
@@ -934,7 +950,7 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok, |
|
|
|
} |
|
|
|
if (!ADVANCE_CHAR(str, tok)) |
|
|
|
goto out; |
|
|
|
} /* while(POP_CHAR) */ |
|
|
|
} /* while(PEEK_CHAR) */ |
|
|
|
|
|
|
|
out: |
|
|
|
if (c && |
|
|
|