]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-mail: message-parser - Always properly finish parsed input
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Wed, 24 Feb 2021 15:51:19 +0000 (17:51 +0200)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Tue, 2 Mar 2021 09:44:40 +0000 (11:44 +0200)
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))

src/lib-mail/message-parser.c

index 40a504da0af4d9cbb12d1373405c34fed818f97b..6e45fe2caf524bdb1b3cfdb6968744aaa066d99e 100644 (file)
@@ -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);