dovecot-1.2: Message parsing/reading: If read returns failure, d...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Dec 13 09:38:58 EET 2008
details: http://hg.dovecot.org/dovecot-1.2/rev/c63cc3580150
changeset: 8526:c63cc3580150
user: Timo Sirainen <tss at iki.fi>
date: Sat Dec 13 08:36:59 2008 +0200
description:
Message parsing/reading: If read returns failure, don't ignore the error.
diffstat:
7 files changed, 84 insertions(+), 38 deletions(-)
src/imap/imap-fetch-body.c | 55 ++++++++++++++++++++++++----------
src/lib-mail/istream-header-filter.c | 15 +++++++--
src/lib-mail/message-send.c | 13 ++++----
src/lib-mail/message-send.h | 6 +--
src/lib-mail/message-size.c | 21 +++++++++---
src/lib-mail/message-size.h | 8 ++--
src/lib-storage/index/index-mail.c | 4 +-
diffs (294 lines):
diff -r 9c8b0f8075d2 -r c63cc3580150 src/imap/imap-fetch-body.c
--- 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 @@ struct partial_cache {
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)
-{
- bool cr_skipped;
-
+static void fetch_read_error(struct imap_fetch_context *ctx)
+{
+ 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 @@ static bool seek_partial(unsigned int se
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 @@ static off_t imap_fetch_send(struct imap
}
}
}
+ 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 @@ static int fetch_data(struct imap_fetch_
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 @@ static int fetch_header_partial_from(str
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 @@ fetch_body_header_fields(struct imap_fet
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.
diff -r 9c8b0f8075d2 -r c63cc3580150 src/lib-mail/istream-header-filter.c
--- 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 @@ static ssize_t read_header(struct header
}
}
- 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.
diff -r 9c8b0f8075d2 -r c63cc3580150 src/lib-mail/message-send.c
--- 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 @@ void message_skip_virtual(struct istream
cr_skipped = msg[i-1] == '\r';
}
+ i_assert(ret == -1);
+ return input->stream_errno == 0 ? 0 : -1;
}
diff -r 9c8b0f8075d2 -r c63cc3580150 src/lib-mail/message-send.h
--- 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 @@ struct message_size;
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
diff -r 9c8b0f8075d2 -r c63cc3580150 src/lib-mail/message-size.c
--- 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 @@ void message_get_header_size(struct istr
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 @@ void message_get_body_size(struct istrea
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,
diff -r 9c8b0f8075d2 -r c63cc3580150 src/lib-mail/message-size.h
--- 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 @@ struct message_size {
/* 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,
diff -r 9c8b0f8075d2 -r c63cc3580150 src/lib-storage/index/index-mail.c
--- 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 @@ int index_mail_init_stream(struct index_
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 @@ int index_mail_init_stream(struct index_
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,
More information about the dovecot-cvs
mailing list