]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-mail: message-parser - Fix assert-crash if parsing is stopped early
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Thu, 28 May 2020 09:49:33 +0000 (12:49 +0300)
committerTimo Sirainen <timo.sirainen@open-xchange.com>
Thu, 28 May 2020 09:52:41 +0000 (12:52 +0300)
Some callers don't want to parse the full message.

Fixes:
Panic: file message-parser.c: line 793 (message_parser_deinit_from_parts): assertion failed: (ctx->nested_parts_count == 0)

src/lib-mail/message-parser.c
src/lib-mail/test-message-parser.c

index 5e74fb7b5bc0dc169a8430bfd0f94e40fcc3624e..6370a1bff714be68b34bb5f6bfb405cc3f9ee8bf 100644 (file)
@@ -787,7 +787,9 @@ int message_parser_deinit_from_parts(struct message_parser_ctx **_ctx,
        if (ctx->hdr_parser_ctx != NULL)
                message_parse_header_deinit(&ctx->hdr_parser_ctx);
        boundary_remove_until(ctx, NULL);
-       i_assert(ctx->nested_parts_count == 0);
+       /* caller might have stopped the parsing early */
+       i_assert(ctx->nested_parts_count == 0 ||
+                i_stream_have_bytes_left(ctx->input));
 
        i_stream_unref(&ctx->input);
        array_free(&ctx->next_part_stack);
index 33ce79462b35ac642b21487630008c4e8ee8ed02..1b782f5df2edb858c1ee9f76f8853f7a265b89b1 100644 (file)
@@ -175,6 +175,36 @@ static void test_message_parser_small_blocks(void)
        test_end();
 }
 
+static void test_message_parser_stop_early(void)
+{
+       struct message_parser_ctx *parser;
+       struct istream *input;
+       struct message_part *parts;
+       struct message_block block;
+       unsigned int i;
+       pool_t pool;
+       int ret;
+
+       test_begin("message parser stop early");
+       pool = pool_alloconly_create("message parser", 10240);
+       input = test_istream_create(test_msg);
+
+       test_istream_set_allow_eof(input, FALSE);
+       for (i = 1; i <= TEST_MSG_LEN+1; i++) {
+               i_stream_seek(input, 0);
+               test_istream_set_size(input, i);
+               parser = message_parser_init(pool, input, &set_empty);
+               while ((ret = message_parser_parse_next_block(parser,
+                                                             &block)) > 0) ;
+               test_assert(ret == 0);
+               message_parser_deinit(&parser, &parts);
+       }
+
+       i_stream_unref(&input);
+       pool_unref(&pool);
+       test_end();
+}
+
 static void test_message_parser_truncated_mime_headers(void)
 {
 static const char input_msg[] =
@@ -1058,6 +1088,7 @@ int main(void)
 {
        static void (*const test_functions[])(void) = {
                test_message_parser_small_blocks,
+               test_message_parser_stop_early,
                test_message_parser_truncated_mime_headers,
                test_message_parser_truncated_mime_headers2,
                test_message_parser_truncated_mime_headers3,