From: Timo Sirainen Date: Thu, 28 May 2020 09:49:33 +0000 (+0300) Subject: lib-mail: message-parser - Fix assert-crash if parsing is stopped early X-Git-Tag: 2.3.11.2~32 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b38875a48acec9c91fb23576f78b2297e0d92a22;p=thirdparty%2Fdovecot%2Fcore.git lib-mail: message-parser - Fix assert-crash if parsing is stopped early 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) --- diff --git a/src/lib-mail/message-parser.c b/src/lib-mail/message-parser.c index 5e74fb7b5b..6370a1bff7 100644 --- a/src/lib-mail/message-parser.c +++ b/src/lib-mail/message-parser.c @@ -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); diff --git a/src/lib-mail/test-message-parser.c b/src/lib-mail/test-message-parser.c index 33ce79462b..1b782f5df2 100644 --- a/src/lib-mail/test-message-parser.c +++ b/src/lib-mail/test-message-parser.c @@ -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,