summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Haszlakiewicz <erh+git@nimenees.com>2012-12-23 08:39:46 -0800
committerEric Haszlakiewicz <erh+git@nimenees.com>2012-12-23 08:39:46 -0800
commit56166e2dff56e2c7dff6d2085587dc8da3c48ebe (patch)
treea7a34bde6c01d787dfbeba0758de0323768e3095
parentd7de3aa24b2255ebe52b43e654d0a87e5c5a09a0 (diff)
parent197cb1d1c1aecd5084b705eee0fafbd4d8da812d (diff)
downloadjson-c-56166e2dff56e2c7dff6d2085587dc8da3c48ebe.tar.gz
Merge pull request #51 from remicollet/issue-dyndepth
Make maximum recursion depth a runtime option
-rw-r--r--ChangeLog3
-rw-r--r--json_tokener.c21
-rw-r--r--json_tokener.h7
3 files changed, 23 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 42a3da9..2d55020 100644
--- 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
diff --git a/json_tokener.c b/json_tokener.c
index 05357fb..6c5924b 100644
--- a/json_tokener.c
+++ b/json_tokener.c
@@ -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;
}
diff --git a/json_tokener.h b/json_tokener.h
index d104c75..3da520a 100644
--- a/json_tokener.h
+++ b/json_tokener.h
@@ -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);