dovecot-2.2: lib-index: Fixed mail_cache_lookup_headers() when f...

dovecot at dovecot.org dovecot at dovecot.org
Wed May 29 03:48:06 EEST 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/e7c474011934
changeset: 16414:e7c474011934
user:      Timo Sirainen <tss at iki.fi>
date:      Wed May 29 03:47:38 2013 +0300
description:
lib-index: Fixed mail_cache_lookup_headers() when fields were still in memory buffer.

diffstat:

 src/lib-index/mail-cache-lookup.c |  41 +++++++++++++++++++-------------------
 1 files changed, 21 insertions(+), 20 deletions(-)

diffs (128 lines):

diff -r 1a565186aee0 -r e7c474011934 src/lib-index/mail-cache-lookup.c
--- a/src/lib-index/mail-cache-lookup.c	Wed May 29 03:27:09 2013 +0300
+++ b/src/lib-index/mail-cache-lookup.c	Wed May 29 03:47:38 2013 +0300
@@ -434,17 +434,18 @@
 }
 
 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 @@
 	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 @@
 			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
 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 @@
 	buffer_t *buf;
 	int ret;
 
+	*pool_r = NULL;
+
 	if (fields_count == 0)
 		return 1;
 
@@ -534,6 +540,7 @@
 	/* 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 @@
 
 	/* 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 @@
 
 		/* 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 @@
 			      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;
 }


More information about the dovecot-cvs mailing list