]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Catch input stream errors when parsing mail.
authorTimo Sirainen <tss@iki.fi>
Tue, 22 Jan 2013 14:31:17 +0000 (16:31 +0200)
committerTimo Sirainen <tss@iki.fi>
Tue, 22 Jan 2013 14:31:17 +0000 (16:31 +0200)
src/lib-storage/index/index-mail-headers.c
src/lib-storage/index/index-mail.c
src/lib-storage/index/index-mail.h

index fb14c52a17de4b374d8aa5704e07079dd3a5a787..1e3b985101f5e57f079835544fb971592edeecfc 100644 (file)
@@ -374,6 +374,7 @@ index_mail_cache_parse_init(struct mail *_mail, struct istream *input)
        input2 = tee_i_stream_create_child(mail->data.tee_stream);
 
        index_mail_parse_header_init(mail, NULL);
+       mail->data.parser_input = input;
        mail->data.parser_ctx =
                message_parser_init(mail->data_pool, input,
                                    hdr_parser_flags, msg_parser_flags);
@@ -386,10 +387,13 @@ static void index_mail_init_parser(struct index_mail *mail)
        struct index_mail_data *data = &mail->data;
        struct message_part *parts;
 
-       if (data->parser_ctx != NULL)
+       if (data->parser_ctx != NULL) {
+               data->parser_input = NULL;
                (void)message_parser_deinit(&data->parser_ctx, &parts);
+       }
 
        if (data->parts == NULL) {
+               data->parser_input = data->stream;
                data->parser_ctx = message_parser_init(mail->data_pool,
                                                       data->stream,
                                                       hdr_parser_flags,
index cfc1480420c2751766d779bc3e1910decb73e0a5..c014d6c5a90a6694604675bc46434dc49697101a 100644 (file)
@@ -751,13 +751,38 @@ static void index_mail_cache_dates(struct index_mail *mail)
 static int index_mail_parse_body_finish(struct index_mail *mail,
                                        enum index_cache_field field)
 {
-       if (message_parser_deinit(&mail->data.parser_ctx,
-                                 &mail->data.parts) < 0) {
-               mail_set_cache_corrupted(&mail->mail.mail,
-                                        MAIL_FETCH_MESSAGE_PARTS);
+       struct istream *parser_input = mail->data.parser_input;
+       int ret;
+
+       if (parser_input == NULL) {
+               ret = message_parser_deinit(&mail->data.parser_ctx,
+                                           &mail->data.parts) < 0 ? 0 : 1;
+       } else {
+               mail->data.parser_input = NULL;
+               i_stream_ref(parser_input);
+               ret = message_parser_deinit(&mail->data.parser_ctx,
+                                           &mail->data.parts) < 0 ? 0 : 1;
+               if (parser_input->stream_errno != 0) {
+                       errno = parser_input->stream_errno;
+                       mail_storage_set_critical(mail->mail.mail.box->storage,
+                                       "read(%s) failed: %m",
+                                       i_stream_get_name(parser_input));
+                       ret = -1;
+               }
+               i_assert(i_stream_read(parser_input) == -1 &&
+                        !i_stream_have_bytes_left(parser_input));
+               i_stream_unref(&parser_input);
+       }
+       if (ret <= 0) {
+               if (ret == 0) {
+                       mail_set_cache_corrupted(&mail->mail.mail,
+                                                MAIL_FETCH_MESSAGE_PARTS);
+               }
+               mail->data.parts = NULL;
                mail->data.parsed_bodystructure = FALSE;
                return -1;
        }
+
        if (mail->data.no_caching) {
                /* if we're here because we aborted parsing, don't get any
                   further or we may crash while generating output from
@@ -1150,6 +1175,7 @@ static void index_mail_close_streams_full(struct index_mail *mail, bool closing)
                        mail_set_cache_corrupted(&mail->mail.mail,
                                                 MAIL_FETCH_MESSAGE_PARTS);
                }
+               mail->data.parser_input = NULL;
        }
        if (data->filter_stream != NULL)
                i_stream_unref(&data->filter_stream);
index 7210387d6d663b0b8244b9d028abeb5a1646696e..45d8f4f7a3c4a705ce298265d72b7ed0b50a69e2 100644 (file)
@@ -96,6 +96,7 @@ struct index_mail_data {
        struct istream *stream, *filter_stream;
        struct tee_istream *tee_stream;
        struct message_size hdr_size, body_size;
+       struct istream *parser_input;
        struct message_parser_ctx *parser_ctx;
        int parsing_count;
        ARRAY_TYPE(keywords) keywords;