Issue #103: allow Infinity and -Infinity to be parsed.
This commit is contained in:
@@ -3,6 +3,10 @@
|
|||||||
/* Define if .gnu.warning accepts long strings. */
|
/* Define if .gnu.warning accepts long strings. */
|
||||||
#undef HAS_GNU_WARNING_LONG
|
#undef HAS_GNU_WARNING_LONG
|
||||||
|
|
||||||
|
/* Define to 1 if you have the declaration of `INFINITY', and to 0 if you
|
||||||
|
don't. */
|
||||||
|
#undef HAVE_DECL_INFINITY
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `isinf', and to 0 if you don't.
|
/* Define to 1 if you have the declaration of `isinf', and to 0 if you don't.
|
||||||
*/
|
*/
|
||||||
#undef HAVE_DECL_ISINF
|
#undef HAVE_DECL_ISINF
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ AC_FUNC_MEMCMP
|
|||||||
AC_FUNC_MALLOC
|
AC_FUNC_MALLOC
|
||||||
AC_FUNC_REALLOC
|
AC_FUNC_REALLOC
|
||||||
AC_CHECK_FUNCS(strcasecmp strdup strerror snprintf vsnprintf vasprintf open vsyslog strncasecmp setlocale)
|
AC_CHECK_FUNCS(strcasecmp strdup strerror snprintf vsnprintf vasprintf open vsyslog strncasecmp setlocale)
|
||||||
|
AC_CHECK_DECLS([INFINITY], [], [], [[#include <math.h>]])
|
||||||
AC_CHECK_DECLS([nan], [], [], [[#include <math.h>]])
|
AC_CHECK_DECLS([nan], [], [], [[#include <math.h>]])
|
||||||
AC_CHECK_DECLS([isnan], [], [], [[#include <math.h>]])
|
AC_CHECK_DECLS([isnan], [], [], [[#include <math.h>]])
|
||||||
AC_CHECK_DECLS([isinf], [], [], [[#include <math.h>]])
|
AC_CHECK_DECLS([isinf], [], [], [[#include <math.h>]])
|
||||||
|
|||||||
@@ -57,6 +57,8 @@
|
|||||||
|
|
||||||
static const char json_null_str[] = "null";
|
static const char json_null_str[] = "null";
|
||||||
static const int json_null_str_len = sizeof(json_null_str) - 1;
|
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_nan_str[] = "NaN";
|
static const char json_nan_str[] = "NaN";
|
||||||
static const int json_nan_str_len = sizeof(json_nan_str) - 1;
|
static const int json_nan_str_len = sizeof(json_nan_str) - 1;
|
||||||
static const char json_true_str[] = "true";
|
static const char json_true_str[] = "true";
|
||||||
@@ -275,6 +277,12 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
saved_state = json_tokener_state_array;
|
saved_state = json_tokener_state_array;
|
||||||
current = json_object_new_array();
|
current = json_object_new_array();
|
||||||
break;
|
break;
|
||||||
|
case 'I':
|
||||||
|
case 'i':
|
||||||
|
state = json_tokener_state_inf;
|
||||||
|
printbuf_reset(tok->pb);
|
||||||
|
tok->st_pos = 0;
|
||||||
|
goto redo_char;
|
||||||
case 'N':
|
case 'N':
|
||||||
case 'n':
|
case 'n':
|
||||||
state = json_tokener_state_null; // or NaN
|
state = json_tokener_state_null; // or NaN
|
||||||
@@ -332,7 +340,41 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
tok->depth--;
|
tok->depth--;
|
||||||
goto redo_char;
|
goto redo_char;
|
||||||
|
|
||||||
case json_tokener_state_null:
|
case json_tokener_state_inf: /* aka starts with 'i' */
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
int size_inf;
|
||||||
|
int is_negative = 0;
|
||||||
|
|
||||||
|
printbuf_memappend_fast(tok->pb, &c, 1);
|
||||||
|
size = json_min(tok->st_pos+1, json_null_str_len);
|
||||||
|
size_inf = json_min(tok->st_pos+1, json_inf_str_len);
|
||||||
|
char *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)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (tok->st_pos == json_inf_str_len)
|
||||||
|
{
|
||||||
|
current = json_object_new_double(is_negative ? -INFINITY : INFINITY);
|
||||||
|
saved_state = json_tokener_state_finish;
|
||||||
|
state = json_tokener_state_eatws;
|
||||||
|
goto redo_char;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tok->err = json_tokener_error_parse_unexpected;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
tok->st_pos++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case json_tokener_state_null: /* aka starts with 'n' */
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
int size_nan;
|
int size_nan;
|
||||||
@@ -628,6 +670,14 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
}
|
}
|
||||||
if (case_len>0)
|
if (case_len>0)
|
||||||
printbuf_memappend_fast(tok->pb, case_start, case_len);
|
printbuf_memappend_fast(tok->pb, case_start, case_len);
|
||||||
|
|
||||||
|
// Check for -Infinity
|
||||||
|
if (tok->pb->buf[0] == '-' && case_len == 1 &&
|
||||||
|
(c == 'i' || c == 'I'))
|
||||||
|
{
|
||||||
|
state = json_tokener_state_inf;
|
||||||
|
goto redo_char;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
int64_t num64;
|
int64_t num64;
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ enum json_tokener_state {
|
|||||||
json_tokener_state_object_value_add,
|
json_tokener_state_object_value_add,
|
||||||
json_tokener_state_object_sep,
|
json_tokener_state_object_sep,
|
||||||
json_tokener_state_array_after_sep,
|
json_tokener_state_array_after_sep,
|
||||||
json_tokener_state_object_field_start_after_sep
|
json_tokener_state_object_field_start_after_sep,
|
||||||
|
json_tokener_state_inf
|
||||||
};
|
};
|
||||||
|
|
||||||
struct json_tokener_srec
|
struct json_tokener_srec
|
||||||
|
|||||||
@@ -21,4 +21,8 @@
|
|||||||
#error This platform does not have nan()
|
#error This platform does not have nan()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_DECL_INFINITY
|
||||||
|
#error This platform does not have INFINITY
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -51,6 +51,34 @@ static void test_basic_parse()
|
|||||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||||
json_object_put(new_obj);
|
json_object_put(new_obj);
|
||||||
|
|
||||||
|
new_obj = json_tokener_parse("-NaN"); /* non-sensical, returns null */
|
||||||
|
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||||
|
json_object_put(new_obj);
|
||||||
|
|
||||||
|
new_obj = json_tokener_parse("Inf"); /* must use full string, returns null */
|
||||||
|
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||||
|
json_object_put(new_obj);
|
||||||
|
|
||||||
|
new_obj = json_tokener_parse("inf"); /* must use full string, returns null */
|
||||||
|
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||||
|
json_object_put(new_obj);
|
||||||
|
|
||||||
|
new_obj = json_tokener_parse("Infinity");
|
||||||
|
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||||
|
json_object_put(new_obj);
|
||||||
|
|
||||||
|
new_obj = json_tokener_parse("infinity");
|
||||||
|
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||||
|
json_object_put(new_obj);
|
||||||
|
|
||||||
|
new_obj = json_tokener_parse("-Infinity");
|
||||||
|
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||||
|
json_object_put(new_obj);
|
||||||
|
|
||||||
|
new_obj = json_tokener_parse("-infinity");
|
||||||
|
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||||
|
json_object_put(new_obj);
|
||||||
|
|
||||||
new_obj = json_tokener_parse("True");
|
new_obj = json_tokener_parse("True");
|
||||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||||
json_object_put(new_obj);
|
json_object_put(new_obj);
|
||||||
|
|||||||
@@ -4,6 +4,13 @@ new_obj.to_string()="foo"
|
|||||||
new_obj.to_string()="ABC"
|
new_obj.to_string()="ABC"
|
||||||
new_obj.to_string()=null
|
new_obj.to_string()=null
|
||||||
new_obj.to_string()=NaN
|
new_obj.to_string()=NaN
|
||||||
|
new_obj.to_string()=null
|
||||||
|
new_obj.to_string()=null
|
||||||
|
new_obj.to_string()=null
|
||||||
|
new_obj.to_string()=Infinity
|
||||||
|
new_obj.to_string()=Infinity
|
||||||
|
new_obj.to_string()=-Infinity
|
||||||
|
new_obj.to_string()=-Infinity
|
||||||
new_obj.to_string()=true
|
new_obj.to_string()=true
|
||||||
new_obj.to_string()=12
|
new_obj.to_string()=12
|
||||||
new_obj.to_string()=12.3
|
new_obj.to_string()=12.3
|
||||||
|
|||||||
Reference in New Issue
Block a user