]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: Fixed calling json_parse_skip_next() within arrays
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 4 Feb 2016 11:32:58 +0000 (13:32 +0200)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 4 Feb 2016 11:32:58 +0000 (13:32 +0200)
src/lib/json-parser.c
src/lib/test-json-parser.c

index a92a5ae12b720da27c22914622bf20ce5182c9b5..14ade58a814ead64180be7e0ef579ff361ed7d9a 100644 (file)
@@ -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)
index 33403404bba3c85b0f98686bb2573da0e9745682..ac7ee8ec8d979ff626a4747a31059ce7e02cc3aa 100644 (file)
@@ -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();