kore

An easy to use, scalable and secure web application framework for writing web APIs in C.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

commit 8c32f8f63bcc8e3ef58e5ffd4a6908661446eb5e
parent 8aa9af1f0c3b3ebb3f0321eb945d0ca2807575d4
Author: Joris Vink <joris@coders.se>
Date:   Thu, 19 Nov 2020 09:07:42 +0100

Small improvements to JSON parser.

- Don't allow garbage at the end of the JSON data (except whitespace).
- Don't allow objects such as {"a":"b",} or [a,]

Diffstat:
src/json.c | 29+++++++++++++++++++++++++----
1 file changed, 25 insertions(+), 4 deletions(-)

diff --git a/src/json.c b/src/json.c @@ -99,6 +99,13 @@ kore_json_parse(struct kore_json *json) return (KORE_RESULT_ERROR); } + /* Don't allow garbage at the end. */ + json_consume_whitespace(json); + if (json->offset != json->length) { + json->error = KORE_JSON_ERR_INVALID_JSON; + return (KORE_RESULT_ERROR); + } + return (KORE_RESULT_OK); } @@ -479,7 +486,7 @@ json_parse_object(struct kore_json *json, struct kore_json_item *object) u_int8_t ch; char *key; struct kore_json_item *item; - int ret, type; + int ret, type, hasnext; if (json->depth++ >= KORE_JSON_DEPTH_MAX) { json->error = KORE_JSON_ERR_DEPTH; @@ -487,6 +494,7 @@ json_parse_object(struct kore_json *json, struct kore_json_item *object) } key = NULL; + hasnext = 0; ret = KORE_RESULT_ERROR; if (!json_next(json, &ch)) @@ -504,6 +512,10 @@ json_parse_object(struct kore_json *json, struct kore_json_item *object) switch (ch) { case '}': + if (hasnext) { + json->error = KORE_JSON_ERR_INVALID_JSON; + goto cleanup; + } json->offset++; ret = KORE_RESULT_OK; goto cleanup; @@ -546,8 +558,10 @@ json_parse_object(struct kore_json *json, struct kore_json_item *object) if (!json_next(json, &ch)) goto cleanup; - if (ch == ',') + if (ch == ',') { + hasnext = 1; continue; + } if (ch == '}') { ret = KORE_RESULT_OK; @@ -572,7 +586,7 @@ json_parse_array(struct kore_json *json, struct kore_json_item *array) u_int8_t ch; char *key; struct kore_json_item *item; - int ret, type; + int ret, type, hasnext; if (json->depth++ >= KORE_JSON_DEPTH_MAX) { json->error = KORE_JSON_ERR_DEPTH; @@ -580,6 +594,7 @@ json_parse_array(struct kore_json *json, struct kore_json_item *array) } key = NULL; + hasnext = 0; ret = KORE_RESULT_ERROR; if (!json_next(json, &ch)) @@ -596,6 +611,10 @@ json_parse_array(struct kore_json *json, struct kore_json_item *array) goto cleanup; if (ch == ']') { + if (hasnext) { + json->error = KORE_JSON_ERR_INVALID_JSON; + goto cleanup; + } json->offset++; ret = KORE_RESULT_OK; goto cleanup; @@ -617,8 +636,10 @@ json_parse_array(struct kore_json *json, struct kore_json_item *array) if (!json_next(json, &ch)) goto cleanup; - if (ch == ',') + if (ch == ',') { + hasnext = 1; continue; + } if (ch == ']') { ret = KORE_RESULT_OK;