"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/lib-storage/index/index-mail-headers.c" between
dovecot-2.3.16.tar.gz and dovecot-2.3.17.tar.gz

About: Dovecot is an IMAP and POP3 server, written with security primarily in mind.

index-mail-headers.c  (dovecot-2.3.16):index-mail-headers.c  (dovecot-2.3.17)
skipping to change at line 25 skipping to change at line 25
#include "imap-bodystructure.h" #include "imap-bodystructure.h"
#include "index-storage.h" #include "index-storage.h"
#include "index-mail.h" #include "index-mail.h"
static const struct message_parser_settings msg_parser_set = { static const struct message_parser_settings msg_parser_set = {
.hdr_flags = MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP | .hdr_flags = MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP |
MESSAGE_HEADER_PARSER_FLAG_DROP_CR, MESSAGE_HEADER_PARSER_FLAG_DROP_CR,
.flags = MESSAGE_PARSER_FLAG_SKIP_BODY_BLOCK, .flags = MESSAGE_PARSER_FLAG_SKIP_BODY_BLOCK,
}; };
static void index_mail_filter_stream_destroy(struct index_mail *mail);
static int header_line_cmp(const struct index_mail_line *l1, static int header_line_cmp(const struct index_mail_line *l1,
const struct index_mail_line *l2) const struct index_mail_line *l2)
{ {
int diff; int diff;
diff = (int)l1->field_idx - (int)l2->field_idx; diff = (int)l1->field_idx - (int)l2->field_idx;
return diff != 0 ? diff : return diff != 0 ? diff :
(int)l1->line_num - (int)l2->line_num; (int)l1->line_num - (int)l2->line_num;
} }
void index_mail_parse_header_deinit(struct index_mail *mail)
{
mail->data.header_parser_initialized = FALSE;
}
static void index_mail_parse_header_finish(struct index_mail *mail) static void index_mail_parse_header_finish(struct index_mail *mail)
{ {
struct mail *_mail = &mail->mail.mail; struct mail *_mail = &mail->mail.mail;
const struct index_mail_line *lines; const struct index_mail_line *lines;
const unsigned char *header; const unsigned char *header;
const uint8_t *match; const uint8_t *match;
buffer_t *buf; buffer_t *buf;
unsigned int i, j, count, match_idx, match_count; unsigned int i, j, count, match_idx, match_count;
bool noncontiguous; bool noncontiguous;
skipping to change at line 137 skipping to change at line 144
mail_cache_field_can_add(_mail->transaction->cache_trans, mail_cache_field_can_add(_mail->transaction->cache_trans,
_mail->seq, match_idx)) { _mail->seq, match_idx)) {
/* this header doesn't exist. remember that. */ /* this header doesn't exist. remember that. */
i_assert((match[match_idx] & i_assert((match[match_idx] &
HEADER_MATCH_FLAG_FOUND) == 0); HEADER_MATCH_FLAG_FOUND) == 0);
index_mail_cache_add_idx(mail, match_idx, "", 0); index_mail_cache_add_idx(mail, match_idx, "", 0);
} }
} }
mail->data.dont_cache_field_idx = UINT_MAX; mail->data.dont_cache_field_idx = UINT_MAX;
mail->data.header_parser_initialized = FALSE; index_mail_parse_header_deinit(mail);
} }
static unsigned int static unsigned int
get_header_field_idx(struct mailbox *box, const char *field) get_header_field_idx(struct mailbox *box, const char *field)
{ {
struct mail_cache_field header_field; struct mail_cache_field header_field;
i_zero(&header_field); i_zero(&header_field);
header_field.type = MAIL_CACHE_FIELD_HEADER; header_field.type = MAIL_CACHE_FIELD_HEADER;
/* Always register with NO decision. The field should be added soon /* Always register with NO decision. The field should be added soon
skipping to change at line 198 skipping to change at line 205
} }
} }
void index_mail_parse_header_init(struct index_mail *mail, void index_mail_parse_header_init(struct index_mail *mail,
struct mailbox_header_lookup_ctx *headers) struct mailbox_header_lookup_ctx *headers)
{ {
struct index_mail_data *data = &mail->data; struct index_mail_data *data = &mail->data;
const uint8_t *match; const uint8_t *match;
unsigned int i, field_idx, match_count; unsigned int i, field_idx, match_count;
index_mail_filter_stream_destroy(mail);
i_assert(!mail->data.header_parser_initialized); i_assert(!mail->data.header_parser_initialized);
mail->header_seq = data->seq; mail->header_seq = data->seq;
if (mail->header_data == NULL) { if (mail->header_data == NULL) {
mail->header_data = buffer_create_dynamic(default_pool, 4096); mail->header_data = buffer_create_dynamic(default_pool, 4096);
i_array_init(&mail->header_lines, 32); i_array_init(&mail->header_lines, 32);
i_array_init(&mail->header_match, 32); i_array_init(&mail->header_match, 32);
i_array_init(&mail->header_match_lines, 32); i_array_init(&mail->header_match_lines, 32);
mail->header_match_value = HEADER_MATCH_SKIP_COUNT; mail->header_match_value = HEADER_MATCH_SKIP_COUNT;
} else { } else {
skipping to change at line 428 skipping to change at line 436
data->parts = NULL; data->parts = NULL;
} }
if (data->parts == NULL || data->parts != parts) { if (data->parts == NULL || data->parts != parts) {
/* The previous parsing didn't finish, so we're /* The previous parsing didn't finish, so we're
re-parsing the header. The new parts don't have data re-parsing the header. The new parts don't have data
filled anymore. */ filled anymore. */
data->parsed_bodystructure_header = FALSE; data->parsed_bodystructure_header = FALSE;
} }
} }
/* make sure parsing starts from the beginning of the stream */
i_stream_seek(mail->data.stream, 0);
if (data->parts == NULL) { if (data->parts == NULL) {
data->parser_input = data->stream; data->parser_input = data->stream;
data->parser_ctx = message_parser_init(mail->mail.data_pool, data->parser_ctx = message_parser_init(mail->mail.data_pool,
data->stream, data->stream,
&msg_parser_set); &msg_parser_set);
} else { } else {
data->parser_ctx = data->parser_ctx =
message_parser_init_from_parts(data->parts, message_parser_init_from_parts(data->parts,
data->stream, data->stream,
&msg_parser_set); &msg_parser_set);
skipping to change at line 466 skipping to change at line 476
index_mail_parse_part_header_cb, index_mail_parse_part_header_cb,
mail); mail);
} else { } else {
/* just read the header */ /* just read the header */
i_assert(!data->save_bodystructure_body || i_assert(!data->save_bodystructure_body ||
data->parser_ctx != NULL); data->parser_ctx != NULL);
message_parse_header(data->stream, &data->hdr_size, message_parse_header(data->stream, &data->hdr_size,
msg_parser_set.hdr_flags, msg_parser_set.hdr_flags,
index_mail_parse_header_cb, mail); index_mail_parse_header_cb, mail);
} }
if (index_mail_stream_check_failure(mail) < 0) if (index_mail_stream_check_failure(mail) < 0) {
index_mail_parse_header_deinit(mail);
return -1; return -1;
}
i_assert(!mail->data.header_parser_initialized);
data->hdr_size_set = TRUE; data->hdr_size_set = TRUE;
data->access_part &= ENUM_NEGATE(PARSE_HDR); data->access_part &= ENUM_NEGATE(PARSE_HDR);
return 0; return 0;
} }
int index_mail_parse_headers(struct index_mail *mail, int index_mail_parse_headers(struct index_mail *mail,
struct mailbox_header_lookup_ctx *headers, struct mailbox_header_lookup_ctx *headers,
const char *reason) const char *reason)
{ {
struct index_mail_data *data = &mail->data; struct index_mail_data *data = &mail->data;
skipping to change at line 890 skipping to change at line 903
} }
static void static void
header_cache_callback(struct header_filter_istream *input ATTR_UNUSED, header_cache_callback(struct header_filter_istream *input ATTR_UNUSED,
struct message_header_line *hdr, struct message_header_line *hdr,
bool *matched ATTR_UNUSED, struct index_mail *mail) bool *matched ATTR_UNUSED, struct index_mail *mail)
{ {
index_mail_parse_header(NULL, hdr, mail); index_mail_parse_header(NULL, hdr, mail);
} }
static void index_mail_filter_stream_destroy(struct index_mail *mail)
{
if (mail->data.filter_stream == NULL)
return;
const unsigned char *data;
size_t size;
/* read through the previous filter_stream. this makes sure that the
fields are added to cache, and most importantly it resets
header_parser_initialized=FALSE so we don't assert on it. */
while (i_stream_read_more(mail->data.filter_stream, &data, &size) > 0)
i_stream_skip(mail->data.filter_stream, size);
if (mail->data.header_parser_initialized) {
/* istream failed while reading the header */
i_assert(mail->data.filter_stream->stream_errno != 0);
index_mail_parse_header_deinit(mail);
}
i_stream_destroy(&mail->data.filter_stream);
}
int index_mail_get_header_stream(struct mail *_mail, int index_mail_get_header_stream(struct mail *_mail,
struct mailbox_header_lookup_ctx *headers, struct mailbox_header_lookup_ctx *headers,
struct istream **stream_r) struct istream **stream_r)
{ {
struct index_mail *mail = INDEX_MAIL(_mail); struct index_mail *mail = INDEX_MAIL(_mail);
struct istream *input; struct istream *input;
string_t *dest; string_t *dest;
if (mail->data.filter_stream != NULL) { index_mail_filter_stream_destroy(mail);
const unsigned char *data;
size_t size;
/* read through the previous filter_stream. this makes sure
that the fields are added to cache, and most importantly it
resets header_parser_initialized=FALSE so we don't assert
on it. */
while (i_stream_read_more(mail->data.filter_stream, &data, &size)
> 0)
i_stream_skip(mail->data.filter_stream, size);
i_stream_destroy(&mail->data.filter_stream);
}
if (mail->data.save_bodystructure_header) { if (mail->data.save_bodystructure_header) {
/* we have to parse the header. */ /* we have to parse the header. */
const char *reason = const char *reason =
index_mail_cache_reason(_mail, "bodystructure"); index_mail_cache_reason(_mail, "bodystructure");
if (index_mail_parse_headers(mail, headers, reason) < 0) if (index_mail_parse_headers(mail, headers, reason) < 0)
return -1; return -1;
} }
dest = str_new(mail->mail.data_pool, 256); dest = str_new(mail->mail.data_pool, 256);
 End of changes. 9 change blocks. 
15 lines changed or deleted 37 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)