Mercurial > dovecot > original-hg > dovecot-1.2
changeset 8526:c63cc3580150 HEAD
Message parsing/reading: If read returns failure, don't ignore the error.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 13 Dec 2008 08:36:59 +0200 |
parents | 9c8b0f8075d2 |
children | 6d07bedcdb80 |
files | src/imap/imap-fetch-body.c src/lib-mail/istream-header-filter.c src/lib-mail/message-send.c src/lib-mail/message-send.h src/lib-mail/message-size.c src/lib-mail/message-size.h src/lib-storage/index/index-mail.c |
diffstat | 7 files changed, 82 insertions(+), 36 deletions(-) [+] |
line wrap: on
line diff
--- a/src/imap/imap-fetch-body.c Sat Dec 13 08:36:16 2008 +0200 +++ b/src/imap/imap-fetch-body.c Sat Dec 13 08:36:59 2008 +0200 @@ -43,12 +43,18 @@ static struct partial_cache last_partial = { 0, 0, 0, 0, { 0, 0, 0 } }; -static bool seek_partial(unsigned int select_counter, unsigned int uid, - struct partial_cache *partial, struct istream *stream, - uoff_t virtual_skip) +static void fetch_read_error(struct imap_fetch_context *ctx) { - bool cr_skipped; + errno = ctx->cur_input->stream_errno; + i_error("FETCH for mailbox %s UID %u " + "failed to read message input: %m", + mailbox_get_name(ctx->mail->box), ctx->mail->uid); +} +static int seek_partial(unsigned int select_counter, unsigned int uid, + struct partial_cache *partial, struct istream *stream, + uoff_t virtual_skip, bool *cr_skipped_r) +{ if (select_counter == partial->select_counter && uid == partial->uid && stream->v_offset == partial->physical_start && virtual_skip >= partial->pos.virtual_size) { @@ -64,11 +70,12 @@ i_stream_seek(stream, partial->physical_start + partial->pos.physical_size); - message_skip_virtual(stream, virtual_skip, &partial->pos, - partial->cr_skipped, &cr_skipped); + if (message_skip_virtual(stream, virtual_skip, &partial->pos, + partial->cr_skipped, cr_skipped_r) < 0) + return -1; partial->cr_skipped = FALSE; - return cr_skipped; + return 0; } static uoff_t get_send_size(const struct imap_fetch_body_data *body, @@ -174,6 +181,10 @@ } } } + if (input->stream_errno != 0) { + fetch_read_error(ctx); + return -1; + } if (add_missing_eoh && sent + 2 == virtual_size) { /* Netscape missing EOH workaround. */ @@ -307,12 +318,18 @@ return -1; if (!ctx->update_partial) { - message_skip_virtual(ctx->cur_input, body->skip, NULL, FALSE, - &ctx->skip_cr); + if (message_skip_virtual(ctx->cur_input, body->skip, NULL, + FALSE, &ctx->skip_cr) < 0) { + fetch_read_error(ctx); + return -1; + } } else { - ctx->skip_cr = - seek_partial(ctx->select_counter, ctx->cur_mail->uid, - &last_partial, ctx->cur_input, body->skip); + if (seek_partial(ctx->select_counter, ctx->cur_mail->uid, + &last_partial, ctx->cur_input, body->skip, + &ctx->skip_cr) < 0) { + fetch_read_error(ctx); + return -1; + } } return fetch_stream(ctx, size); @@ -407,7 +424,10 @@ ctx->update_partial = FALSE; old_offset = ctx->cur_input->v_offset; - message_get_header_size(ctx->cur_input, &msg_size, NULL); + if (message_get_header_size(ctx->cur_input, &msg_size, NULL) < 0) { + fetch_read_error(ctx); + return -1; + } i_stream_seek(ctx->cur_input, old_offset); if (!ctx->cur_have_eoh && @@ -455,7 +475,10 @@ ctx->update_partial = FALSE; old_offset = ctx->cur_input->v_offset; - message_get_body_size(ctx->cur_input, &size, NULL); + if (message_get_body_size(ctx->cur_input, &size, NULL) < 0) { + fetch_read_error(ctx); + return -1; + } i_stream_seek(ctx->cur_input, old_offset); /* FIXME: We'll just always add the end of headers line now.
--- a/src/lib-mail/istream-header-filter.c Sat Dec 13 08:36:16 2008 +0200 +++ b/src/lib-mail/istream-header-filter.c Sat Dec 13 08:36:59 2008 +0200 @@ -234,9 +234,18 @@ } } - if (hdr_ret < 0 && !mstream->seen_eoh && mstream->add_missing_eoh) { - mstream->seen_eoh = TRUE; - add_eol(mstream); + if (hdr_ret < 0) { + if (mstream->istream.parent->stream_errno != 0) { + mstream->istream.istream.stream_errno = + mstream->istream.parent->stream_errno; + mstream->istream.istream.eof = + mstream->istream.parent->eof; + return -1; + } + if (!mstream->seen_eoh && mstream->add_missing_eoh) { + mstream->seen_eoh = TRUE; + add_eol(mstream); + } } /* don't copy eof here because we're only returning headers here.
--- a/src/lib-mail/message-send.c Sat Dec 13 08:36:16 2008 +0200 +++ b/src/lib-mail/message-send.c Sat Dec 13 08:36:59 2008 +0200 @@ -7,21 +7,22 @@ #include "message-send.h" #include "message-size.h" -void message_skip_virtual(struct istream *input, uoff_t virtual_skip, - struct message_size *msg_size, - bool cr_skipped, bool *last_cr) +int message_skip_virtual(struct istream *input, uoff_t virtual_skip, + struct message_size *msg_size, + bool cr_skipped, bool *last_cr) { const unsigned char *msg; size_t i, size, startpos; + int ret; if (virtual_skip == 0) { *last_cr = cr_skipped; - return; + return 0; } *last_cr = FALSE; startpos = 0; - while (i_stream_read_data(input, &msg, &size, startpos) > 0) { + while ((ret = i_stream_read_data(input, &msg, &size, startpos)) > 0) { for (i = startpos; i < size && virtual_skip > 0; i++) { virtual_skip--; @@ -64,4 +65,6 @@ cr_skipped = msg[i-1] == '\r'; } + i_assert(ret == -1); + return input->stream_errno == 0 ? 0 : -1; }
--- a/src/lib-mail/message-send.h Sat Dec 13 08:36:16 2008 +0200 +++ b/src/lib-mail/message-send.h Sat Dec 13 08:36:59 2008 +0200 @@ -7,8 +7,8 @@ NULL. If cr_skipped is TRUE and first character is \n, it's not treated as \r\n. last_cr is set to TRUE if last character we skipped was \r, meaning that next character should be \n and you shouldn't treat it as \r\n. */ -void message_skip_virtual(struct istream *input, uoff_t virtual_skip, - struct message_size *msg_size, - bool cr_skipped, bool *last_cr); +int message_skip_virtual(struct istream *input, uoff_t virtual_skip, + struct message_size *msg_size, + bool cr_skipped, bool *last_cr); #endif
--- a/src/lib-mail/message-size.c Sat Dec 13 08:36:16 2008 +0200 +++ b/src/lib-mail/message-size.c Sat Dec 13 08:36:59 2008 +0200 @@ -5,11 +5,12 @@ #include "message-parser.h" #include "message-size.h" -void message_get_header_size(struct istream *input, struct message_size *hdr, - bool *has_nuls) +int message_get_header_size(struct istream *input, struct message_size *hdr, + bool *has_nuls) { const unsigned char *msg; size_t i, size, startpos, missing_cr_count; + int ret = 0; memset(hdr, 0, sizeof(struct message_size)); if (has_nuls != NULL) @@ -54,27 +55,31 @@ hdr->physical_size += i - startpos; } + if (input->stream_errno != 0) + ret = -1; i_stream_skip(input, startpos); hdr->physical_size += startpos; hdr->virtual_size = hdr->physical_size + missing_cr_count; i_assert(hdr->virtual_size >= hdr->physical_size); + return ret; } -void message_get_body_size(struct istream *input, struct message_size *body, - bool *has_nuls) +int message_get_body_size(struct istream *input, struct message_size *body, + bool *has_nuls) { const unsigned char *msg; size_t i, size, missing_cr_count; bool last_cr; + int ret = 0; memset(body, 0, sizeof(struct message_size)); if (has_nuls != NULL) *has_nuls = FALSE; missing_cr_count = 0; last_cr = FALSE; - if (i_stream_read_data(input, &msg, &size, 0) <= 0) - return; + if ((ret = i_stream_read_data(input, &msg, &size, 0)) <= 0) + return ret < 0 && input->stream_errno != 0 ? -1 : 0; if (msg[0] == '\n') missing_cr_count++; @@ -104,11 +109,15 @@ body->physical_size += i - 1; } while (i_stream_read_data(input, &msg, &size, 1) > 0); + if (input->stream_errno != 0) + ret = -1; + i_stream_skip(input, 1); body->physical_size++; body->virtual_size = body->physical_size + missing_cr_count; i_assert(body->virtual_size >= body->physical_size); + return ret; } void message_size_add(struct message_size *dest,
--- a/src/lib-mail/message-size.h Sat Dec 13 08:36:16 2008 +0200 +++ b/src/lib-mail/message-size.h Sat Dec 13 08:36:59 2008 +0200 @@ -9,11 +9,11 @@ /* Calculate size of message header. Leave the input point to first character in body. */ -void message_get_header_size(struct istream *input, struct message_size *hdr, - bool *has_nuls); +int message_get_header_size(struct istream *input, struct message_size *hdr, + bool *has_nuls); /* Calculate size of message body. */ -void message_get_body_size(struct istream *input, struct message_size *body, - bool *has_nuls); +int message_get_body_size(struct istream *input, struct message_size *body, + bool *has_nuls); /* Sum contents of src into dest. */ void message_size_add(struct message_size *dest,
--- a/src/lib-storage/index/index-mail.c Sat Dec 13 08:36:16 2008 +0200 +++ b/src/lib-storage/index/index-mail.c Sat Dec 13 08:36:59 2008 +0200 @@ -795,6 +795,7 @@ struct istream **stream_r) { struct index_mail_data *data = &mail->data; + int ret; i_stream_set_destroy_callback(data->stream, index_mail_stream_destroy_callback, mail); @@ -845,10 +846,11 @@ data->physical_size = data->hdr_size.physical_size + data->body_size.physical_size; } + ret = index_mail_stream_check_failure(mail); i_stream_seek(data->stream, 0); *stream_r = data->stream; - return 0; + return ret; } static int index_mail_parse_bodystructure(struct index_mail *mail,