]> git.ipfire.org Git - thirdparty/json-c.git/commitdiff
Issue #15: add a way to set a JSON_TOKENER_STRICT flag to forbid commas at the end...
authorEric Haszlakiewicz <erh+git@nimenees.com>
Mon, 1 Apr 2013 01:05:36 +0000 (20:05 -0500)
committerEric Haszlakiewicz <erh+git@nimenees.com>
Mon, 1 Apr 2013 01:05:36 +0000 (20:05 -0500)
json_tokener.c
json_tokener.h
tests/test_parse.c
tests/test_parse.expected

index 6d50bc2333b0622303c300c0013bbec797ffad7e..b2b47f9d8806eb33447613d376275c14e27f7728 100644 (file)
@@ -624,8 +624,15 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
       }
       break;
 
+    case json_tokener_state_array_after_sep:
     case json_tokener_state_array:
       if(c == ']') {
+               if (state == json_tokener_state_array_after_sep &&
+                       (tok->flags & JSON_TOKENER_STRICT))
+               {
+                       tok->err = json_tokener_error_parse_unexpected;
+                       goto out;
+               }
        saved_state = json_tokener_state_finish;
        state = json_tokener_state_eatws;
       } else {
@@ -651,7 +658,7 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
        saved_state = json_tokener_state_finish;
        state = json_tokener_state_eatws;
       } else if(c == ',') {
-       saved_state = json_tokener_state_array;
+       saved_state = json_tokener_state_array_after_sep;
        state = json_tokener_state_eatws;
       } else {
        tok->err = json_tokener_error_parse_array;
@@ -660,7 +667,14 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
       break;
 
     case json_tokener_state_object_field_start:
+    case json_tokener_state_object_field_start_after_sep:
       if(c == '}') {
+               if (state == json_tokener_state_object_field_start_after_sep &&
+                   (tok->flags & JSON_TOKENER_STRICT))
+               {
+                       tok->err = json_tokener_error_parse_unexpected;
+                       goto out;
+               }
        saved_state = json_tokener_state_finish;
        state = json_tokener_state_eatws;
       } else if (c == '"' || c == '\'') {
@@ -731,7 +745,7 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
        saved_state = json_tokener_state_finish;
        state = json_tokener_state_eatws;
       } else if(c == ',') {
-       saved_state = json_tokener_state_object_field_start;
+       saved_state = json_tokener_state_object_field_start_after_sep;
        state = json_tokener_state_eatws;
       } else {
        tok->err = json_tokener_error_parse_object_value_sep;
@@ -771,3 +785,8 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
           json_tokener_errors[tok->err], tok->char_offset);
   return NULL;
 }
+
+void json_tokener_set_flags(struct json_tokener *tok, int flags)
+{
+       tok->flags = flags;
+}
index 3da520aadfe5d6cb3343f28c4b98db905a80f076..08e5ff7fce7960628ff363fb2b3cac949c694b73 100644 (file)
@@ -58,7 +58,9 @@ enum json_tokener_state {
   json_tokener_state_object_field_end,
   json_tokener_state_object_value,
   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_object_field_start_after_sep
 };
 
 struct json_tokener_srec
@@ -80,8 +82,21 @@ struct json_tokener
   unsigned int ucs_char;
   char quote_char;
   struct json_tokener_srec *stack;
+  int flags;
 };
 
+/**
+ * Be strict when parsing JSON input.  Use caution with
+ * this flag as what is considered valid may become more
+ * restrictive from one release to the next, causing your
+ * code to fail on previously working input.
+ *
+ * This flag is not set by default.
+ *
+ * @see json_tokener_set_flags()
+ */
+#define JSON_TOKENER_STRICT  0x01
+
 /**
  * Given an error previously returned by json_tokener_get_error(),
  * return a human readable description of the error.
@@ -116,6 +131,11 @@ extern void json_tokener_reset(struct json_tokener *tok);
 extern struct json_object* json_tokener_parse(const char *str);
 extern struct json_object* json_tokener_parse_verbose(const char *str, enum json_tokener_error *error);
 
+/**
+ * Set flags that control how parsing will be done.
+ */
+extern void json_tokener_set_flags(struct json_tokener *tok, int flags);
+
 /** 
  * Parse a string and return a non-NULL json_object if a valid JSON value
  * is found.  The string does not need to be a JSON object or array;
index 481cb123d8b6c7c79f9d842239e53afc78bb2c3d..1a59a6bddba84e47c287fe092be6a6b890fc30d2 100644 (file)
@@ -183,6 +183,9 @@ struct incremental_step {
        { "[1,2,3,]",         -1, -1, json_tokener_success, 0 },
        { "[1,2,,3,]",        -1, 5, json_tokener_error_parse_unexpected, 0 },
 
+       { "[1,2,3,]",         -1, 7, json_tokener_error_parse_unexpected, 3 },
+       { "{\"a\":1,}",         -1, 7, json_tokener_error_parse_unexpected, 3 },
+
        { NULL, -1, -1, json_tokener_success, 0 },
 };
 
@@ -215,6 +218,12 @@ static void test_incremental_parse()
                struct incremental_step *step = &incremental_steps[ii];
                int length = step->length;
                int expected_char_offset = step->char_offset;
+
+               if (step->reset_tokener & 2)
+                       json_tokener_set_flags(tok, JSON_TOKENER_STRICT);
+               else
+                       json_tokener_set_flags(tok, 0);
+
                if (length == -1)
                        length = strlen(step->string_to_parse);
                if (expected_char_offset == -1)
@@ -264,7 +273,7 @@ static void test_incremental_parse()
                if (new_obj)
                        json_object_put(new_obj);
 
-               if (step->reset_tokener)
+               if (step->reset_tokener & 1)
                        json_tokener_reset(tok);
 
                if (this_step_ok)
index 814dc62f03be5995e2a25368c72ccbc847000ad7..f0af0fa1b7523e24d3400458f3ae73118d5f8ee1 100644 (file)
@@ -51,5 +51,7 @@ json_tokener_parse_ex(tok, "\t"        ,   4) ... OK: got object of type [string
 json_tokener_parse_ex(tok, [1,2,3]     ,   7) ... OK: got object of type [array]: [ 1, 2, 3 ]
 json_tokener_parse_ex(tok, [1,2,3,]    ,   8) ... OK: got object of type [array]: [ 1, 2, 3 ]
 json_tokener_parse_ex(tok, [1,2,,3,]   ,   9) ... OK: got correct error: unexpected character
-End Incremental Tests OK=27 ERROR=0
+json_tokener_parse_ex(tok, [1,2,3,]    ,   8) ... OK: got correct error: unexpected character
+json_tokener_parse_ex(tok, {"a":1,}    ,   8) ... OK: got correct error: unexpected character
+End Incremental Tests OK=29 ERROR=0
 ==================================