changeset 19709:31389e4b4677

lib: Fixed calling json_parse_skip_next() within arrays
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Thu, 04 Feb 2016 13:32:58 +0200
parents 6d45c0bb9b30
children 25ea1b5c514b
files src/lib/json-parser.c src/lib/test-json-parser.c
diffstat 2 files changed, 35 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib/json-parser.c	Thu Feb 04 13:31:59 2016 +0200
+++ b/src/lib/json-parser.c	Thu Feb 04 13:32:58 2016 +0200
@@ -21,6 +21,7 @@
 	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 @@
 			/* 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 @@
 	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)
--- a/src/lib/test-json-parser.c	Thu Feb 04 13:31:59 2016 +0200
+++ b/src/lib/test-json-parser.c	Thu Feb 04 13:32:58 2016 +0200
@@ -163,6 +163,34 @@
 	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 @@
 {
 	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();