dovecot-1.1: Changed message_parser_deinit() to return -1 if the...
dovecot at dovecot.org
dovecot at dovecot.org
Thu Feb 14 22:43:28 EET 2008
details: http://hg.dovecot.org/dovecot-1.1/rev/289765861d66
changeset: 7243:289765861d66
user: Timo Sirainen <tss at iki.fi>
date: Thu Feb 14 22:43:28 2008 +0200
description:
Changed message_parser_deinit() to return -1 if the parser was using
preparsed broken message parts. Callers catch the error and mark the cache
file corrupted.
diffstat:
7 files changed, 51 insertions(+), 16 deletions(-)
src/lib-mail/message-parser.c | 15 ++++++++++++---
src/lib-mail/message-parser.h | 5 ++++-
src/lib-mail/message-search.c | 17 +++++++++++++----
src/lib-storage/index/index-mail-headers.c | 3 ++-
src/lib-storage/index/index-mail.c | 16 +++++++++++++---
src/plugins/fts/fts-storage.c | 5 +++--
src/tests/test-mail.c | 6 ++++--
diffs (197 lines):
diff -r 8cfa61f98e32 -r 289765861d66 src/lib-mail/message-parser.c
--- a/src/lib-mail/message-parser.c Thu Feb 14 22:40:23 2008 +0200
+++ b/src/lib-mail/message-parser.c Thu Feb 14 22:43:28 2008 +0200
@@ -41,6 +41,7 @@ struct message_parser_ctx {
struct message_block *block_r);
unsigned int part_seen_content_type:1;
+ unsigned int broken:1;
};
message_part_header_callback_t *null_message_part_header_callback = NULL;
@@ -663,6 +664,11 @@ static int preparsed_parse_next_header(s
/* return empty block as end of headers */
block_r->hdr = NULL;
block_r->size = 0;
+
+ i_assert(ctx->skip == 0);
+ if (ctx->input->v_offset != ctx->part->physical_pos +
+ ctx->part->header_size.physical_size)
+ ctx->broken = TRUE;
return 1;
}
@@ -718,15 +724,18 @@ message_parser_init_from_parts(struct me
return ctx;
}
-struct message_part *message_parser_deinit(struct message_parser_ctx **_ctx)
+int message_parser_deinit(struct message_parser_ctx **_ctx,
+ struct message_part **parts_r)
{
struct message_parser_ctx *ctx = *_ctx;
- struct message_part *parts = ctx->parts;
+ int ret = ctx->broken ? -1 : 0;
*_ctx = NULL;
+ *parts_r = ctx->parts;
+
i_stream_unref(&ctx->input);
pool_unref(&ctx->parser_pool);
- return parts;
+ return ret;
}
int message_parser_parse_next_block(struct message_parser_ctx *ctx,
diff -r 8cfa61f98e32 -r 289765861d66 src/lib-mail/message-parser.h
--- a/src/lib-mail/message-parser.h Thu Feb 14 22:40:23 2008 +0200
+++ b/src/lib-mail/message-parser.h Thu Feb 14 22:43:28 2008 +0200
@@ -78,7 +78,10 @@ message_parser_init_from_parts(struct me
struct istream *input,
enum message_header_parser_flags hdr_flags,
enum message_parser_flags flags);
-struct message_part *message_parser_deinit(struct message_parser_ctx **ctx);
+/* Returns 0 if parts were returned, -1 we used preparsed parts and they
+ didn't match the current message */
+int message_parser_deinit(struct message_parser_ctx **ctx,
+ struct message_part **parts_r);
/* Read the next block of a message. Returns 1 if block is returned, 0 if
input stream is non-blocking and more data needs to be read, -1 when all is
diff -r 8cfa61f98e32 -r 289765861d66 src/lib-mail/message-search.c
--- a/src/lib-mail/message-search.c Thu Feb 14 22:40:23 2008 +0200
+++ b/src/lib-mail/message-search.c Thu Feb 14 22:43:28 2008 +0200
@@ -214,7 +214,8 @@ message_search_msg_real(struct message_s
MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE;
struct message_parser_ctx *parser_ctx;
struct message_block raw_block;
- int ret = 0;
+ struct message_part *new_parts;
+ int ret;
message_search_reset(ctx);
@@ -229,13 +230,21 @@ message_search_msg_real(struct message_s
while ((ret = message_parser_parse_next_block(parser_ctx,
&raw_block)) > 0) {
- if ((ret = message_search_more(ctx, &raw_block)) != 0)
+ if (message_search_more(ctx, &raw_block)) {
+ ret = 1;
break;
+ }
}
i_assert(ret != 0);
- if (ret < 0 && input->stream_errno == 0)
+ if (ret < 0 && input->stream_errno == 0) {
+ /* normal exit */
ret = 0;
- (void)message_parser_deinit(&parser_ctx);
+ }
+ if (message_parser_deinit(&parser_ctx, &new_parts) < 0) {
+ /* broken parts */
+ input->stream_errno = 0;
+ ret = -1;
+ }
return ret;
}
diff -r 8cfa61f98e32 -r 289765861d66 src/lib-storage/index/index-mail-headers.c
--- a/src/lib-storage/index/index-mail-headers.c Thu Feb 14 22:40:23 2008 +0200
+++ b/src/lib-storage/index/index-mail-headers.c Thu Feb 14 22:43:28 2008 +0200
@@ -380,9 +380,10 @@ static void index_mail_init_parser(struc
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)
- (void)message_parser_deinit(&data->parser_ctx);
+ (void)message_parser_deinit(&data->parser_ctx, &parts);
if (data->parts == NULL) {
data->parser_ctx = message_parser_init(mail->data_pool,
diff -r 8cfa61f98e32 -r 289765861d66 src/lib-storage/index/index-mail.c
--- a/src/lib-storage/index/index-mail.c Thu Feb 14 22:40:23 2008 +0200
+++ b/src/lib-storage/index/index-mail.c Thu Feb 14 22:43:28 2008 +0200
@@ -702,7 +702,12 @@ static void index_mail_parse_body_finish
static void index_mail_parse_body_finish(struct index_mail *mail,
enum index_cache_field field)
{
- mail->data.parts = message_parser_deinit(&mail->data.parser_ctx);
+ if (message_parser_deinit(&mail->data.parser_ctx,
+ &mail->data.parts) < 0) {
+ mail_set_cache_corrupted(&mail->mail.mail,
+ MAIL_FETCH_MESSAGE_PARTS);
+ return;
+ }
(void)get_cached_msgpart_sizes(mail);
@@ -1026,14 +1031,19 @@ void index_mail_close(struct mail *_mail
void index_mail_close(struct mail *_mail)
{
struct index_mail *mail = (struct index_mail *)_mail;
+ struct message_part *parts;
if (mail->mail.mail.seq != 0) {
index_mail_cache_sizes(mail);
index_mail_cache_dates(mail);
}
- if (mail->data.parser_ctx != NULL)
- (void)message_parser_deinit(&mail->data.parser_ctx);
+ if (mail->data.parser_ctx != NULL) {
+ if (message_parser_deinit(&mail->data.parser_ctx, &parts) < 0) {
+ mail_set_cache_corrupted(_mail,
+ MAIL_FETCH_MESSAGE_PARTS);
+ }
+ }
if (mail->data.filter_stream != NULL)
i_stream_unref(&mail->data.filter_stream);
if (mail->data.stream != NULL) {
diff -r 8cfa61f98e32 -r 289765861d66 src/plugins/fts/fts-storage.c
--- a/src/plugins/fts/fts-storage.c Thu Feb 14 22:40:23 2008 +0200
+++ b/src/plugins/fts/fts-storage.c Thu Feb 14 22:43:28 2008 +0200
@@ -108,7 +108,7 @@ static int fts_build_mail(struct fts_sto
struct message_parser_ctx *parser;
struct message_decoder_context *decoder;
struct message_block raw_block, block;
- struct message_part *prev_part;
+ struct message_part *prev_part, *parts;
int ret;
ctx->uid = uid;
@@ -153,7 +153,8 @@ static int fts_build_mail(struct fts_sto
}
}
}
- (void)message_parser_deinit(&parser);
+ if (message_parser_deinit(&parser, &parts) < 0)
+ mail_set_cache_corrupted(ctx->mail, MAIL_FETCH_MESSAGE_PARTS);
message_decoder_deinit(&decoder);
if (ret == 0) {
diff -r 8cfa61f98e32 -r 289765861d66 src/tests/test-mail.c
--- a/src/tests/test-mail.c Thu Feb 14 22:40:23 2008 +0200
+++ b/src/tests/test-mail.c Thu Feb 14 22:43:28 2008 +0200
@@ -219,7 +219,8 @@ static void test_message_parser(void)
parser = message_parser_init(pool, input, 0, 0);
while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
i_assert(ret < 0);
- parts = message_parser_deinit(&parser);
+ ret = message_parser_deinit(&parser, &parts);
+ i_assert(ret == 0);
i_stream_unref(&input);
input = test_istream_create(test_msg);
@@ -234,7 +235,8 @@ static void test_message_parser(void)
break;
}
}
- parts2 = message_parser_deinit(&parser);
+ ret = message_parser_deinit(&parser, &parts2);
+ i_assert(ret == 0);
i_stream_unref(&input);
if (!msg_parts_cmp(parts, parts2))
More information about the dovecot-cvs
mailing list