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";
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' */
}
if (!ADVANCE_CHAR(str, tok))
goto out;
- } /* while(POP_CHAR) */
+ } /* while(PEEK_CHAR) */
out:
if (c &&