From: Timo Sirainen Date: Sun, 24 Nov 2019 11:03:51 +0000 (+0200) Subject: lib-imap: Fix adding IMAP_ARG_EOL parameter to all unfinished lists X-Git-Tag: 2.3.9~31 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=bc1e8ee82276b2eaebe7e44c2eee93c1c99f36eb;p=thirdparty%2Fdovecot%2Fcore.git lib-imap: Fix adding IMAP_ARG_EOL parameter to all unfinished lists This is a continuation for 6beb5339f163eaa470974ced2bcdf193f130d8a7, which added it only to the last open list, not its parent lists. --- diff --git a/src/lib-imap/imap-parser.c b/src/lib-imap/imap-parser.c index 238d2efa0a..b6c6e63fb1 100644 --- a/src/lib-imap/imap-parser.c +++ b/src/lib-imap/imap-parser.c @@ -742,6 +742,20 @@ static bool imap_parser_read_arg(struct imap_parser *parser) return TRUE; } +static void list_add_ghost_eol(struct imap_arg *list_arg) +{ + struct imap_arg *arg; + + i_assert(list_arg->type == IMAP_ARG_LIST); + + arg = array_append_space(&list_arg->_data.list); + arg->type = IMAP_ARG_EOL; + array_pop_back(&list_arg->_data.list); + + if (list_arg->parent != NULL) + list_add_ghost_eol(list_arg->parent); +} + /* ARG_PARSE_NONE checks that last argument isn't only partially parsed. */ #define IS_UNFINISHED(parser) \ ((parser)->cur_type != ARG_PARSE_NONE || \ @@ -768,9 +782,7 @@ static int finish_line(struct imap_parser *parser, unsigned int count, *args_r = NULL; return -1; } else { - arg = array_append_space(&parser->list_arg->_data.list); - arg->type = IMAP_ARG_EOL; - array_pop_back(&parser->list_arg->_data.list); + list_add_ghost_eol(parser->list_arg); } arg = array_append_space(&parser->root_list); diff --git a/src/lib-imap/test-imap-parser.c b/src/lib-imap/test-imap-parser.c index 7e21668681..93ef8fd59b 100644 --- a/src/lib-imap/test-imap-parser.c +++ b/src/lib-imap/test-imap-parser.c @@ -51,10 +51,39 @@ static void test_imap_parser_crlf(void) test_end(); } +static void test_imap_parser_partial_list(void) +{ + static const char *test_input = "((((foo {1000000}\r\n"; + struct istream *input; + struct imap_parser *parser; + const struct imap_arg *args, *sub_list; + + test_begin("imap parser partial list"); + input = test_istream_create(test_input); + parser = imap_parser_create(input, NULL, 1024); + + (void)i_stream_read(input); + test_assert(imap_parser_read_args(parser, 0, + IMAP_PARSE_FLAG_LITERAL_SIZE, &args) == 1); + for (unsigned int i = 0; i < 4; i++) { + sub_list = imap_arg_as_list(&args[0]); + test_assert(IMAP_ARG_IS_EOL(&args[1])); + args = sub_list; + } + test_assert(imap_arg_atom_equals(&args[0], "foo")); + test_assert(args[1].type == IMAP_ARG_LITERAL_SIZE); + test_assert(IMAP_ARG_IS_EOL(&args[2])); + + imap_parser_unref(&parser); + i_stream_destroy(&input); + test_end(); +} + int main(void) { static void (*const test_functions[])(void) = { test_imap_parser_crlf, + test_imap_parser_partial_list, NULL }; return test_run(test_functions);