Mercurial > dovecot > core-2.2
changeset 19687:2166e0f25e43
lib: Code cleanup to json-parser - assume less that the root is an object
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Mon, 01 Feb 2016 17:00:11 +0200 |
parents | d3aa060852e6 |
children | 0869e8023eab |
files | src/lib/json-parser.c src/lib/test-json-parser.c |
diffstat | 2 files changed, 55 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib/json-parser.c Fri Jan 29 00:08:33 2016 +0200 +++ b/src/lib/json-parser.c Mon Feb 01 17:00:11 2016 +0200 @@ -335,21 +335,16 @@ json_parser_update_input_pos(parser); nested_states = array_get(&parser->nesting, &count); - if (count == 0) { + i_assert(count > 0); + if (count == 1) { /* closing root */ parser->state = JSON_STATE_DONE; return 0; } /* closing a nested object */ - if (count == 1) { - /* we're back to root */ - parser->state = JSON_STATE_OBJECT_NEXT; - } else { - /* back to previous nested object */ - parser->state = nested_states[count-2] == JSON_STATE_OBJECT_OPEN ? - JSON_STATE_OBJECT_NEXT : JSON_STATE_ARRAY_NEXT; - } + parser->state = nested_states[count-2] == JSON_STATE_OBJECT_OPEN ? + JSON_STATE_OBJECT_NEXT : JSON_STATE_ARRAY_NEXT; array_delete(&parser->nesting, count-1, 1); if (parser->nested_skip_count > 0) { @@ -377,6 +372,14 @@ return 1; } +static void json_parser_object_open(struct json_parser *parser) +{ + parser->data++; + parser->state = JSON_STATE_OBJECT_OPEN; + array_append(&parser->nesting, &parser->state, 1); + json_parser_update_input_pos(parser); +} + static int json_try_parse_next(struct json_parser *parser, enum json_type *type_r, const char **value_r) @@ -393,17 +396,12 @@ parser->error = "Object doesn't begin with '{'"; return -1; } - parser->data++; - parser->state = JSON_STATE_OBJECT_OPEN; - json_parser_update_input_pos(parser); + json_parser_object_open(parser); return 0; case JSON_STATE_OBJECT_VALUE: case JSON_STATE_ARRAY_VALUE: if (*parser->data == '{') { - parser->data++; - parser->state = JSON_STATE_OBJECT_OPEN; - array_append(&parser->nesting, &parser->state, 1); - json_parser_update_input_pos(parser); + json_parser_object_open(parser); if (parser->skipping) { parser->nested_skip_count++;
--- a/src/lib/test-json-parser.c Fri Jan 29 00:08:33 2016 +0200 +++ b/src/lib/test-json-parser.c Mon Feb 01 17:00:11 2016 +0200 @@ -163,6 +163,46 @@ test_end(); } +static int test_json_parse_input(const char *test_input) +{ + struct json_parser *parser; + struct istream *input; + enum json_type type; + const char *value, *error; + int ret = 0; + + input = test_istream_create_data(test_input, strlen(test_input)); + parser = json_parser_init(input); + while (json_parse_next(parser, &type, &value) > 0) + ret++; + if (json_parser_deinit(&parser, &error) < 0) + ret = -1; + i_stream_unref(&input); + return ret; +} + +static void test_json_parser_errors(void) +{ + static const char *test_inputs[] = { + "{", + "{:}", + "{\"foo\":}", + "{\"foo\" []}", + "{\"foo\": [1}", + "{\"foo\": [1,]}", + "{\"foo\": [1,]}", + "{\"foo\": 1,}", + "{\"foo\": 1.}}", + "{\"foo\": 1},{}" + }; + unsigned int i; + + test_begin("json parser error handling"); + for (i = 0; i < N_ELEMENTS(test_inputs); i++) + test_assert_idx(test_json_parse_input(test_inputs[i]) < 0, i); + test_end(); +} + static void test_json_append_escaped(void) { string_t *str = t_str_new(32); @@ -189,6 +229,7 @@ { test_json_parser_success(TRUE); test_json_parser_success(FALSE); + test_json_parser_errors(); test_json_append_escaped(); test_json_append_escaped_data(); }