From: Timo Sirainen Date: Wed, 24 Feb 2021 15:51:19 +0000 (+0200) Subject: lib-mail: message-parser - Always properly finish parsed input X-Git-Tag: 2.3.14~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4ea5787c89b80ecf70e4a8c03cb454a686c3ab19;p=thirdparty%2Fdovecot%2Fcore.git lib-mail: message-parser - Always properly finish parsed input If the caller hadn't called message_parser_parse_next_block() after seeing EOF in the istream, the deinit could have crashed with: Panic: file message-parser.c: line 802 (message_parser_deinit_from_parts): assertion failed: (ctx->nested_parts_count == 0 || i_stream_have_bytes_left(ctx->input)) --- diff --git a/src/lib-mail/message-parser.c b/src/lib-mail/message-parser.c index 40a504da0a..6e45fe2caf 100644 --- a/src/lib-mail/message-parser.c +++ b/src/lib-mail/message-parser.c @@ -796,10 +796,18 @@ 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); + if (ctx->part != NULL) { + /* If the whole message has been parsed, the parts are + usually finished in message_parser_parse_next_block(). + However, it's possible that the caller finishes reading + through the istream without calling + message_parser_parse_next_block() afterwards. In that case + we still need to finish these parts. */ + while (ctx->part->parent != NULL) + message_part_finish(ctx); + } boundary_remove_until(ctx, NULL); - /* caller might have stopped the parsing early */ - i_assert(ctx->nested_parts_count == 0 || - i_stream_have_bytes_left(ctx->input)); + i_assert(ctx->nested_parts_count == 0); i_stream_unref(&ctx->input); array_free(&ctx->next_part_stack);