[dovecot-cvs] dovecot/src/lib-index mail-cache-transaction.c, 1.45, 1.46

cras at dovecot.org cras at dovecot.org
Fri Oct 28 13:52:05 EEST 2005


Update of /var/lib/cvs/dovecot/src/lib-index
In directory talvi:/tmp/cvs-serv21734/lib-index

Modified Files:
	mail-cache-transaction.c 
Log Message:
mail_cache_delete(): Make sure we don't get to infinite loop if cache
records contain a loop.



Index: mail-cache-transaction.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-cache-transaction.c,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -d -r1.45 -r1.46
--- mail-cache-transaction.c	30 Sep 2005 18:46:30 -0000	1.45
+++ mail-cache-transaction.c	28 Oct 2005 10:52:02 -0000	1.46
@@ -773,9 +773,24 @@
 	return 0;
 }
 
+static int find_offset(array_t *array, uint32_t offset)
+{
+	ARRAY_SET_TYPE(array, uint32_t);
+	const uint32_t *offsets;
+	unsigned int i, count;
+
+	offsets = array_get(array, &count);
+	for (i = 0; i < count; i++) {
+		if (offsets[i] == offset)
+			return TRUE;
+	}
+	return FALSE;
+}
+
 int mail_cache_delete(struct mail_cache *cache, uint32_t offset)
 {
 	const struct mail_cache_record *cache_rec;
+	array_t ARRAY_DEFINE(tmp_offsets, uint32_t);
 
 	i_assert(cache->locked);
 
@@ -789,12 +804,29 @@
 	   the data. also it's actually useful as some index views are still
 	   able to ask cached data from messages that have already been
 	   expunged. */
-	do {
+	t_push();
+	ARRAY_CREATE(&tmp_offsets, pool_datastack_create(), uint32_t, 8);
+	array_append(&tmp_offsets, &offset, 1);
+	for (;;) {
 		cache->hdr_copy.deleted_space += cache_rec->size;
 		if (mail_cache_get_record(cache, cache_rec->prev_offset,
-					  &cache_rec) < 0)
+					  &cache_rec) < 0) {
+			t_pop();
 			return -1;
-	} while (cache_rec != NULL);
+		}
+
+		if (cache_rec == NULL)
+			break;
+
+		if (find_offset(&tmp_offsets, cache_rec->prev_offset)) {
+			mail_cache_set_corrupted(cache,
+						 "record list is circular");
+			t_pop();
+			return -1;
+		}
+		array_append(&tmp_offsets, &cache_rec->prev_offset, 1);
+	}
+	t_pop();
 
 	cache->hdr_modified = TRUE;
 	return 0;



More information about the dovecot-cvs mailing list