]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-imap: Fix adding IMAP_ARG_EOL parameter to all unfinished lists
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Sun, 24 Nov 2019 11:03:51 +0000 (13:03 +0200)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Mon, 25 Nov 2019 07:27:42 +0000 (09:27 +0200)
This is a continuation for 6beb5339f163eaa470974ced2bcdf193f130d8a7,
which added it only to the last open list, not its parent lists.

src/lib-imap/imap-parser.c
src/lib-imap/test-imap-parser.c

index 238d2efa0a5696c1020f2b0f7f2fdc7a1d649ae6..b6c6e63fb1a6405b1abafcfa508737e07776cf19 100644 (file)
@@ -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);
index 7e2166868137211393af8daf40b2c6f46b5b8138..93ef8fd59b92ed058a77c33f6da195883ed249f0 100644 (file)
@@ -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);