]> granicus.if.org Git - json-c/commitdiff
Make maximum recursion depth a runtime option
authorRemi Collet <fedora@famillecollet.com>
Tue, 27 Nov 2012 08:01:45 +0000 (09:01 +0100)
committerRemi Collet <fedora@famillecollet.com>
Tue, 27 Nov 2012 08:01:45 +0000 (09:01 +0100)
ChangeLog
json_tokener.c
json_tokener.h

index 42a3da99820fe395f7dc7f7c8e0d539d452ac341..2d5502087e6728b44716c5ee93a1e6b74a8bba12 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,9 @@ NEXT.VERSION
      You should change your build to use appropriate -I and -l options.
      A compatibility shim is in place so builds using the old name will
      continue to work, but that will be removed in the next release.
+  * Maximum recursion depth is now a runtime option.
+     json_tokener_new() is provided for compatibility.
+     json_tokener_new_ex(depth)
 
 0.10
 
index f5fa8d6030540e3d2d954809b692fe06325ff3c1..72cfe2a7b20b3aa4df1b1fb92b527b4516ef48ac 100644 (file)
@@ -85,22 +85,33 @@ enum json_tokener_error json_tokener_get_error(json_tokener *tok)
 #define DECODE_SURROGATE_PAIR(hi,lo) ((((hi) & 0x3FF) << 10) + ((lo) & 0x3FF) + 0x10000)
 static unsigned char utf8_replacement_char[3] = { 0xEF, 0xBF, 0xBD };
 
-
-struct json_tokener* json_tokener_new(void)
+struct json_tokener* json_tokener_new_ex(int depth)
 {
   struct json_tokener *tok;
 
   tok = (struct json_tokener*)calloc(1, sizeof(struct json_tokener));
   if (!tok) return NULL;
+  tok->stack = (struct json_tokener*)calloc(depth, sizeof(struct json_tokener_srec));
+  if (!tok->stack) {
+    free(tok);
+    return NULL;
+  }
   tok->pb = printbuf_new();
+  tok->max_depth = depth;
   json_tokener_reset(tok);
   return tok;
 }
 
+struct json_tokener* json_tokener_new(void)
+{
+  return json_tokener_new_ex(JSON_TOKENER_DEFAULT_DEPTH);
+}
+
 void json_tokener_free(struct json_tokener *tok)
 {
   json_tokener_reset(tok);
-  if(tok) printbuf_free(tok->pb);
+  if (tok->pb) printbuf_free(tok->pb);
+  if (tok->stack) free(tok->stack);
   free(tok);
 }
 
@@ -602,7 +613,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(tok->depth >= JSON_TOKENER_MAX_DEPTH-1) {
+       if(tok->depth >= tok->max_depth-1) {
          tok->err = json_tokener_error_depth;
          goto out;
        }
@@ -682,7 +693,7 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
       break;
 
     case json_tokener_state_object_value:
-      if(tok->depth >= JSON_TOKENER_MAX_DEPTH-1) {
+      if(tok->depth >= tok->max_depth-1) {
        tok->err = json_tokener_error_depth;
        goto out;
       }
index d104c75f3de72ec24d2108934f7769dab9fafe40..3da520aadfe5d6cb3343f28c4b98db905a80f076 100644 (file)
@@ -69,17 +69,17 @@ struct json_tokener_srec
   char *obj_field_name;
 };
 
-#define JSON_TOKENER_MAX_DEPTH 32
+#define JSON_TOKENER_DEFAULT_DEPTH 32
 
 struct json_tokener
 {
   char *str;
   struct printbuf *pb;
-  int depth, is_double, st_pos, char_offset;
+  int max_depth, depth, is_double, st_pos, char_offset;
   enum json_tokener_error err;
   unsigned int ucs_char;
   char quote_char;
-  struct json_tokener_srec stack[JSON_TOKENER_MAX_DEPTH];
+  struct json_tokener_srec *stack;
 };
 
 /**
@@ -110,6 +110,7 @@ extern const char* json_tokener_errors[];
 enum json_tokener_error json_tokener_get_error(struct json_tokener *tok);
 
 extern struct json_tokener* json_tokener_new(void);
+extern struct json_tokener* json_tokener_new_ex(int depth);
 extern void json_tokener_free(struct json_tokener *tok);
 extern void json_tokener_reset(struct json_tokener *tok);
 extern struct json_object* json_tokener_parse(const char *str);