diff options
author | Eric Haszlakiewicz <erh+git@nimenees.com> | 2012-12-23 08:39:46 -0800 |
---|---|---|
committer | Eric Haszlakiewicz <erh+git@nimenees.com> | 2012-12-23 08:39:46 -0800 |
commit | 56166e2dff56e2c7dff6d2085587dc8da3c48ebe (patch) | |
tree | a7a34bde6c01d787dfbeba0758de0323768e3095 | |
parent | d7de3aa24b2255ebe52b43e654d0a87e5c5a09a0 (diff) | |
parent | 197cb1d1c1aecd5084b705eee0fafbd4d8da812d (diff) | |
download | json-c-56166e2dff56e2c7dff6d2085587dc8da3c48ebe.tar.gz |
Merge pull request #51 from remicollet/issue-dyndepth
Make maximum recursion depth a runtime option
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | json_tokener.c | 21 | ||||
-rw-r--r-- | json_tokener.h | 7 |
3 files changed, 23 insertions, 8 deletions
@@ -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); |