]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-index: Fixed mail_cache_lookup_headers() when fields were still in memory buffer.
authorTimo Sirainen <tss@iki.fi>
Wed, 29 May 2013 00:47:38 +0000 (03:47 +0300)
committerTimo Sirainen <tss@iki.fi>
Wed, 29 May 2013 00:47:38 +0000 (03:47 +0300)
src/lib-index/mail-cache-lookup.c

index 39f3eb02472c61c836747339824fa970e5b1eb16..02c3e3de7094e3df9fa14d4d92ad82f0c15fe2f1 100644 (file)
@@ -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;
 }