# HG changeset patch # User Olaf Wintermann # Date 1729420230 -7200 # Node ID bbf41b9c2658fde756e44f0ad73d5036735d42dd # Parent 0bb7258366a06f11e839fcb57387f5249cd0d740 fix memory leak in json reader when handling incomplete tokens diff -r 0bb7258366a0 -r bbf41b9c2658 src/json.c --- a/src/json.c Sun Oct 20 11:39:54 2024 +0200 +++ b/src/json.c Sun Oct 20 12:30:30 2024 +0200 @@ -427,15 +427,13 @@ switch (token.tokentype) { case CX_JSON_TOKEN_BEGIN_ARRAY: { p->reader_type = CX_JSON_READER_ARRAY_BEGIN; - if (add_state(p, JP_STATE_VALUE_BEGIN_AR)) return -1; - return 1; - //return json_read(p); + ret = add_state(p, JP_STATE_VALUE_BEGIN_AR) ? -1 : 1; + break; } case CX_JSON_TOKEN_BEGIN_OBJECT: { p->reader_type = CX_JSON_READER_OBJECT_BEGIN; - if (add_state(p, JP_STATE_OBJ_NAME_OR_CLOSE)) return -1; - return 1; - //return json_read(p); + ret = add_state(p, JP_STATE_OBJ_NAME_OR_CLOSE) ? -1 : 1; + break; } case CX_JSON_TOKEN_END_ARRAY: { p->value_ready = 0; @@ -454,7 +452,7 @@ p->value_str = str.ptr; p->value_str_len = str.length; } else { - return -1; + ret = -1; } break; } @@ -462,38 +460,39 @@ p->reader_type = CX_JSON_READER_INTEGER; int64_t value; if (parse_integer(token.content, token.length, &value)) { - return -1; + ret = -1; + } else { + p->value_int = value; + p->value_double = (double) value; } - p->value_int = value; - p->value_double = (double) value; break; } case CX_JSON_TOKEN_NUMBER: { p->reader_type = CX_JSON_READER_NUMBER; double value; if (parse_number(token.content, token.length, &value)) { - return -1; + ret = -1; + } else { + p->value_double = value; + p->value_int = (int64_t) value; } - p->value_double = value; - p->value_int = (int64_t) value; break; } case CX_JSON_TOKEN_LITERAL: { p->reader_type = CX_JSON_READER_LITERAL; break; } - default: - return -1; + default: ret = -1; } } else if (state == JP_STATE_ARRAY_SEP_OR_CLOSE) { // expect ',' or ']' if (token.tokentype == CX_JSON_TOKEN_VALUE_SEPARATOR) { p->states[p->nstates] = JP_STATE_VALUE_BEGIN_AR; - return json_read(p); + ret = json_read(p); } else if (token.tokentype == CX_JSON_TOKEN_END_ARRAY) { end_elm(p, CX_JSON_READER_ARRAY_END); } else { - return -1; + ret = -1; } } else if (state == JP_STATE_OBJ_NAME_OR_CLOSE || state == JP_STATE_OBJ_NAME) { if (state == JP_STATE_OBJ_NAME_OR_CLOSE && token.tokentype == CX_JSON_TOKEN_END_OBJECT) { @@ -510,25 +509,29 @@ // next state p->states[p->nstates] = JP_STATE_OBJ_COLON; - return json_read(p); + ret = json_read(p); } } else if (state == JP_STATE_OBJ_COLON) { // expect ':' if (token.tokentype != CX_JSON_TOKEN_NAME_SEPARATOR) return -1; // next state p->states[p->nstates] = 1; - return json_read(p); + ret = json_read(p); } else if (state == 7) { // expect ',' or '}]' if (token.tokentype == CX_JSON_TOKEN_VALUE_SEPARATOR) { p->states[p->nstates] = JP_STATE_OBJ_NAME; - return json_read(p); + ret = json_read(p); } else if (token.tokentype == CX_JSON_TOKEN_END_OBJECT) { end_elm(p, CX_JSON_READER_OBJECT_END); } else { - return -1; + ret = -1; } } + + if (token.alloc > 0) { + free((char*)token.content); + } return ret; }