From 197cb1d1c1aecd5084b705eee0fafbd4d8da812d Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Tue, 27 Nov 2012 09:01:45 +0100 Subject: [PATCH] Make maximum recursion depth a runtime option --- ChangeLog | 3 +++ json_tokener.c | 21 ++++++++++++++++----- json_tokener.h | 7 ++++--- 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 f5fa8d6..72cfe2a 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); -- 2.40.0