From: Timo Sirainen Date: Thu, 4 Feb 2016 11:32:58 +0000 (+0200) Subject: lib: Fixed calling json_parse_skip_next() within arrays X-Git-Tag: 2.2.22.rc1~211 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f6497ac81e6de57870936d538acccb75ce408fc1;p=thirdparty%2Fdovecot%2Fcore.git lib: Fixed calling json_parse_skip_next() within arrays --- diff --git a/src/lib/json-parser.c b/src/lib/json-parser.c index a92a5ae12b..14ade58a81 100644 --- a/src/lib/json-parser.c +++ b/src/lib/json-parser.c @@ -21,6 +21,7 @@ enum json_state { JSON_STATE_ARRAY_VALUE, JSON_STATE_ARRAY_SKIP_STRING, JSON_STATE_ARRAY_NEXT, + JSON_STATE_ARRAY_NEXT_SKIP, JSON_STATE_VALUE, JSON_STATE_DONE }; @@ -536,6 +537,7 @@ json_try_parse_next(struct json_parser *parser, enum json_type *type_r, /* we skipped over the previous value */ parser->skipping = FALSE; } + case JSON_STATE_ARRAY_NEXT_SKIP: if (*parser->data == ']') return json_parse_close_array(parser, type_r); if (*parser->data != ',') { @@ -592,9 +594,12 @@ void json_parse_skip_next(struct json_parser *parser) i_assert(parser->strinput == NULL); i_assert(parser->state == JSON_STATE_OBJECT_COLON || parser->state == JSON_STATE_OBJECT_VALUE || - parser->state == JSON_STATE_ARRAY_VALUE); + parser->state == JSON_STATE_ARRAY_VALUE || + parser->state == JSON_STATE_ARRAY_NEXT); parser->skipping = TRUE; + if (parser->state == JSON_STATE_ARRAY_NEXT) + parser->state = JSON_STATE_ARRAY_NEXT_SKIP; } static void json_strinput_destroyed(struct json_parser *parser) diff --git a/src/lib/test-json-parser.c b/src/lib/test-json-parser.c index 33403404bb..ac7ee8ec8d 100644 --- a/src/lib/test-json-parser.c +++ b/src/lib/test-json-parser.c @@ -163,6 +163,34 @@ static void test_json_parser_success(bool full_size) test_end(); } +static void test_json_parser_skip_array(void) +{ + static const char *test_input = + "[ 1, {\"foo\": 1 }, 2, \"bar\", 3, 1.234, 4, [], 5, [[]], 6, true ]"; + struct json_parser *parser; + struct istream *input; + enum json_type type; + const char *value, *error; + int i; + + test_begin("json parser skip array"); + + input = test_istream_create_data(test_input, strlen(test_input)); + parser = json_parser_init_flags(input, JSON_PARSER_NO_ROOT_OBJECT); + test_assert(json_parse_next(parser, &type, &value) > 0 && + type == JSON_TYPE_ARRAY); + for (i = 1; i <= 6; i++) { + test_assert(json_parse_next(parser, &type, &value) > 0 && + type == JSON_TYPE_NUMBER && atoi(value) == i); + json_parse_skip_next(parser); + } + test_assert(json_parse_next(parser, &type, &value) > 0 && + type == JSON_TYPE_ARRAY_END); + test_assert(json_parser_deinit(&parser, &error) == 0); + i_stream_unref(&input); + test_end(); +} + static int test_json_parse_input(const char *test_input, enum json_parser_flags flags) { @@ -253,6 +281,7 @@ void test_json_parser(void) { test_json_parser_success(TRUE); test_json_parser_success(FALSE); + test_json_parser_skip_array(); test_json_parser_primitive_values(); test_json_parser_errors(); test_json_append_escaped();