Mercurial > dovecot > original-hg > dovecot-1.2
changeset 7243:289765861d66 HEAD
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.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 14 Feb 2008 22:43:28 +0200 |
parents | 8cfa61f98e32 |
children | 673132f88be3 |
files | src/lib-mail/message-parser.c src/lib-mail/message-parser.h src/lib-mail/message-search.c src/lib-storage/index/index-mail-headers.c src/lib-storage/index/index-mail.c src/plugins/fts/fts-storage.c src/tests/test-mail.c |
diffstat | 7 files changed, 51 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- 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_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 @@ /* 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 @@ 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,
--- 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 @@ 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
--- 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_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 @@ 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; }
--- 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(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,
--- 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(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) { 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) {
--- 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 @@ 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 @@ } } } - (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) {
--- 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 @@ 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 @@ 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))