]> git.ipfire.org Git - thirdparty/json-c.git/commitdiff
Issue #103: allow Infinity and -Infinity to be parsed.
authorEric Haszlakiewicz <erh+git@nimenees.com>
Sat, 22 Mar 2014 21:28:40 +0000 (17:28 -0400)
committerEric Haszlakiewicz <erh+git@nimenees.com>
Sat, 22 Mar 2014 21:28:40 +0000 (17:28 -0400)
config.h.in
configure.ac
json_tokener.c
json_tokener.h
math_compat.h
tests/test_parse.c
tests/test_parse.expected

index f24bfbc2d07a87ce577498df7b004b32bdfdafd8..7c8973f38bac3e425d3c7e76d08ce6165b09f53a 100644 (file)
@@ -3,6 +3,10 @@
 /* Define if .gnu.warning accepts long strings. */
 #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.
    */
 #undef HAVE_DECL_ISINF
index 96e24661025b567e9e83461bfff50ec3209f4352..20ad715f31943f0efc7d913f97f5303cc2369df6 100644 (file)
@@ -29,6 +29,7 @@ AC_FUNC_MEMCMP
 AC_FUNC_MALLOC
 AC_FUNC_REALLOC
 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([isnan], [], [], [[#include <math.h>]])
 AC_CHECK_DECLS([isinf], [], [], [[#include <math.h>]])
index 9862f9ef0729e9c9c3b4077bc2226a9c3bbdf870..e4710e48e04f649204cb863ed6c1591ae54f9f63 100644 (file)
@@ -57,6 +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_nan_str[] = "NaN";
 static const int json_nan_str_len = sizeof(json_nan_str) - 1;
 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;
        current = json_object_new_array();
        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':
        state = json_tokener_state_null; // or NaN
@@ -332,7 +340,41 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
       tok->depth--;
       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_nan;
@@ -628,6 +670,14 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
        }
         if (case_len>0)
           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;
index 08e5ff7fce7960628ff363fb2b3cac949c694b73..61f73d2311a9a5936c9380f02bb9b50f95fcd7ad 100644 (file)
@@ -60,7 +60,8 @@ enum json_tokener_state {
   json_tokener_state_object_value_add,
   json_tokener_state_object_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
index d94a4dacfd48513cc5a1e7bbd8ecec21d87a12d1..f40b8faf8fd4202e859cf43d1b3daaaccdba7c0d 100644 (file)
@@ -21,4 +21,8 @@
 #error This platform does not have nan()
 #endif
 
+#ifndef HAVE_DECL_INFINITY
+#error This platform does not have INFINITY
+#endif
+
 #endif
index f0f255026d6d4a1832b17f9f522e7c65a0b3a2c8..8808d0fa61baf432e87b414190633b00961d330e 100644 (file)
@@ -51,6 +51,34 @@ static void test_basic_parse()
        printf("new_obj.to_string()=%s\n", json_object_to_json_string(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");
        printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
        json_object_put(new_obj);
index 378a82b6dad42fe83d309461ca75c70fdf597f2e..d49cbbb18e018126c5a40b58c650eadfaeb1e970 100644 (file)
@@ -4,6 +4,13 @@ new_obj.to_string()="foo"
 new_obj.to_string()="ABC"
 new_obj.to_string()=null
 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()=12
 new_obj.to_string()=12.3