From: Timo Sirainen Date: Wed, 29 May 2013 00:47:38 +0000 (+0300) Subject: lib-index: Fixed mail_cache_lookup_headers() when fields were still in memory buffer. X-Git-Tag: 2.2.3~109 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6d8082441e480cf481bfb3f935d17fc419d789c6;p=thirdparty%2Fdovecot%2Fcore.git lib-index: Fixed mail_cache_lookup_headers() when fields were still in memory buffer. --- diff --git a/src/lib-index/mail-cache-lookup.c b/src/lib-index/mail-cache-lookup.c index 39f3eb0247..02c3e3de70 100644 --- a/src/lib-index/mail-cache-lookup.c +++ b/src/lib-index/mail-cache-lookup.c @@ -434,17 +434,18 @@ int mail_cache_lookup_field(struct mail_cache_view *view, buffer_t *dest_buf, } struct header_lookup_data { - uint32_t offset; uint32_t data_size; + const unsigned char *data; }; struct header_lookup_line { uint32_t line_num; - struct header_lookup_data *data; + struct header_lookup_data *data; }; struct header_lookup_context { struct mail_cache_view *view; + pool_t pool; ARRAY(struct header_lookup_line) lines; }; @@ -461,7 +462,8 @@ static void header_lines_save(struct header_lookup_context *ctx, uint32_t data_size = field->size; struct header_lookup_line hdr_line; struct header_lookup_data *hdr_data; - unsigned int i, lines_count; + void *data_dup; + unsigned int i, lines_count, pos; /* data = { line_nums[], 0, "headers" } */ for (i = 0; data_size >= sizeof(uint32_t); i++) { @@ -470,10 +472,13 @@ static void header_lines_save(struct header_lookup_context *ctx, break; } lines_count = i; + pos = (lines_count+1) * sizeof(uint32_t); - hdr_data = t_new(struct header_lookup_data, 1); - hdr_data->offset = field->offset + (lines_count+1) * sizeof(uint32_t); + hdr_data = p_new(ctx->pool, struct header_lookup_data, 1); hdr_data->data_size = data_size; + hdr_data->data = data_dup = data_size == 0 ? NULL : + p_malloc(ctx->pool, data_size); + memcpy(data_dup, CONST_PTR_OFFSET(field->data, pos), data_size); for (i = 0; i < lines_count; i++) { hdr_line.line_num = lines[i]; @@ -491,14 +496,13 @@ static int header_lookup_line_cmp(const struct header_lookup_line *l1, static int mail_cache_lookup_headers_real(struct mail_cache_view *view, string_t *dest, uint32_t seq, unsigned int field_idxs[], - unsigned int fields_count) + unsigned int fields_count, pool_t *pool_r) { struct mail_cache *cache = view->cache; struct mail_cache_lookup_iterate_ctx iter; struct mail_cache_iterate_field field; struct header_lookup_context ctx; struct header_lookup_line *lines; - const void *data; const unsigned char *p, *start, *end; uint8_t *field_state; unsigned int i, count, max_field = 0; @@ -507,6 +511,8 @@ mail_cache_lookup_headers_real(struct mail_cache_view *view, string_t *dest, buffer_t *buf; int ret; + *pool_r = NULL; + if (fields_count == 0) return 1; @@ -534,6 +540,7 @@ mail_cache_lookup_headers_real(struct mail_cache_view *view, string_t *dest, /* lookup the fields */ memset(&ctx, 0, sizeof(ctx)); ctx.view = view; + ctx.pool = *pool_r = pool_alloconly_create("mail cache headers", 1024); t_array_init(&ctx.lines, 32); mail_cache_lookup_iter_init(view, seq, &iter); @@ -563,17 +570,7 @@ mail_cache_lookup_headers_real(struct mail_cache_view *view, string_t *dest, /* then start filling dest buffer from the headers */ for (i = 0; i < count; i++) { - ret = mail_cache_map(cache, lines[i].data->offset, - lines[i].data->data_size, &data); - if (ret <= 0) { - if (ret < 0) - return -1; - - mail_cache_set_corrupted(cache, - "header record unexpectedly points outside file"); - return -1; - } - start = data; + start = lines[i].data->data; end = start + lines[i].data->data_size; /* find the end of the (multiline) header */ @@ -589,7 +586,7 @@ mail_cache_lookup_headers_real(struct mail_cache_view *view, string_t *dest, /* if there are more lines for this header, the following lines continue after this one. so skip this line. */ - lines[i].data->offset += hdr_size; + lines[i].data->data += hdr_size; lines[i].data->data_size -= hdr_size; } return 1; @@ -599,11 +596,15 @@ int mail_cache_lookup_headers(struct mail_cache_view *view, string_t *dest, uint32_t seq, unsigned int field_idxs[], unsigned int fields_count) { + pool_t pool; int ret; T_BEGIN { ret = mail_cache_lookup_headers_real(view, dest, seq, - field_idxs, fields_count); + field_idxs, fields_count, + &pool); + if (pool != NULL) + pool_unref(&pool); } T_END; return ret; }