diff --git a/json_tokener.c b/json_tokener.c index 48d4109..73cb6d9 100644 --- a/json_tokener.c +++ b/json_tokener.c @@ -107,6 +107,11 @@ struct fjson_tokener *fjson_tokener_new_ex(int depth) { struct fjson_tokener *tok; + /* depth must be at least 1: fjson_tokener_reset() writes stack[0]. + * A non-positive depth would calloc(0, ...) and then overflow. */ + if (depth < 1) + return NULL; + tok = (struct fjson_tokener *)calloc(1, sizeof(struct fjson_tokener)); if (!tok) return NULL; @@ -116,6 +121,11 @@ struct fjson_tokener *fjson_tokener_new_ex(int depth) return NULL; } tok->pb = printbuf_new(); + if (!tok->pb) { + free(tok->stack); + free(tok); + return NULL; + } tok->max_depth = depth; fjson_tokener_reset(tok); return tok; @@ -857,6 +867,13 @@ struct fjson_object *fjson_tokener_parse_ex(struct fjson_tokener *tok, const cha if (c == tok->quote_char) { printbuf_memappend_fast(tok->pb, case_start, str - case_start); obj_field_name = strdup(tok->pb->buf); + if (obj_field_name == NULL) { + /* out of memory: a NULL key would be + * interpreted as an empty slot, so we + * must not continue. */ + tok->err = fjson_tokener_error_parse_eof; + goto out; + } saved_state = fjson_tokener_state_object_field_end; state = fjson_tokener_state_eatws; break;