dovecot-1.2: Minor changes to mailbox list indexing code. Still ...

dovecot at dovecot.org dovecot at dovecot.org
Tue Feb 10 19:46:19 EET 2009


details:   http://hg.dovecot.org/dovecot-1.2/rev/37e118a32cd0
changeset: 8742:37e118a32cd0
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Feb 10 12:46:14 2009 -0500
description:
Minor changes to mailbox list indexing code. Still disabled/non-working.

diffstat:

2 files changed, 49 insertions(+), 39 deletions(-)
src/lib-index/mailbox-list-index-private.h |   14 +++--
src/lib-index/mailbox-list-index.c         |   74 +++++++++++++++-------------

diffs (160 lines):

diff -r d74fdb84ab8b -r 37e118a32cd0 src/lib-index/mailbox-list-index-private.h
--- a/src/lib-index/mailbox-list-index-private.h	Tue Feb 10 12:19:05 2009 -0500
+++ b/src/lib-index/mailbox-list-index-private.h	Tue Feb 10 12:46:14 2009 -0500
@@ -32,26 +32,30 @@ struct mailbox_list_dir_record {
 	/* If non-zero, contains a pointer to updated directory list.
 	   Stored using mail_index_uint32_to_offset(). */
 	uint32_t next_offset;
-	/* Bytes used by this record, including mailbox names. */
+	/* Bytes required to be able to fully read this directory's records.
+	   This includes also bytes used by mailbox names that follow the
+	   records (but doesn't include bytes for mailbox names that point
+	   to earlier offsets in the file). */
 	uint32_t dir_size;
 
 	uint32_t count;
-	/* The records are sorted by their name_hash */
+	/* The records are sorted 1) by their name_hash, 2) the actual name */
 	/* struct mailbox_list_record records[count]; */
 };
 
 struct mailbox_list_record {
 	/* CRC32 hash of the name */
 	uint32_t name_hash;
-	uint32_t uid:31;
+	unsigned int uid:31;
 	/* Set when this record has been marked as deleted. It will be removed
 	   permanently the next time a new record is added to this directory
 	   or on the next index compression. */
-	uint32_t deleted:1;
+	unsigned int deleted:1;
 
 	/* Points to a NUL-terminated record name */
 	uint32_t name_offset;
-	/* the dir offset is stored using mail_index_uint32_to_offset()
+	/* Pointer to child mailboxes or 0 if there are no children.
+	   The offset is stored using mail_index_uint32_to_offset()
 	   since it may change while we're reading */
 	uint32_t dir_offset;
 };
diff -r d74fdb84ab8b -r 37e118a32cd0 src/lib-index/mailbox-list-index.c
--- a/src/lib-index/mailbox-list-index.c	Tue Feb 10 12:19:05 2009 -0500
+++ b/src/lib-index/mailbox-list-index.c	Tue Feb 10 12:46:14 2009 -0500
@@ -388,8 +388,9 @@ mailbox_list_get_name(struct mailbox_lis
 	const char *name;
 
 	if (rec->name_offset >= index->mmap_size) {
-		mailbox_list_index_set_corrupted(index,
-			"record name_offset points outside file");
+		mailbox_list_index_set_corrupted(index, t_strdup_printf(
+			"record name_offset (%u) points outside file (%u)",
+			rec->name_offset, index->mmap_size));
 		return -1;
 	}
 	max_len = index->mmap_size - rec->name_offset;
@@ -398,32 +399,11 @@ mailbox_list_get_name(struct mailbox_lis
 	   because practically it always is even if the file is corrupted.
 	   just make sure we don't crash if it happens. */
 	*name_r = p_strndup(pool, name, max_len);
+	if (*name_r == '\0') {
+		mailbox_list_index_set_corrupted(index, "Empty mailbox name");
+		return -1;
+	}
 	return 0;
-}
-
-static int mailbox_list_record_cmp(const void *_key, const void *_rec)
-{
-	const struct mailbox_list_index_lookup_key *key = _key;
-	const struct mailbox_list_record *rec = _rec;
-	int ret;
-
-	if (key->name_hash < rec->name_hash)
-		return -1;
-	if (key->name_hash > rec->name_hash)
-		return 1;
-
-	T_BEGIN {
-		const char *name;
-
-		if (mailbox_list_get_name(key->index, unsafe_data_stack_pool,
-					  rec, &name) < 0) {
-			*key->failed = TRUE;
-			ret = -1;
-		} else {
-			ret = strcmp(key->name, name);
-		}
-	} T_END;
-	return ret;
 }
 
 int mailbox_list_index_get_dir(struct mailbox_list_index_view *view,
@@ -457,6 +437,12 @@ int mailbox_list_index_get_dir(struct ma
 			return mailbox_list_index_set_corrupted(index,
 				"next_offset points backwards");
 		}
+
+		if (dir->count >
+		    index->mmap_size / sizeof(struct mailbox_list_record)) {
+			return mailbox_list_index_set_corrupted(index,
+				"dir count too large");
+		}
 		if (dir->dir_size < sizeof(*dir) +
 		    dir->count * sizeof(struct mailbox_list_record)) {
 			return mailbox_list_index_set_corrupted(index,
@@ -465,13 +451,7 @@ int mailbox_list_index_get_dir(struct ma
 		cur_offset = next_offset;
 	} while (cur_offset != 0);
 
-	if (dir->count > INT_MAX/sizeof(struct mailbox_list_record)) {
-		mailbox_list_index_set_corrupted(index, "dir count too large");
-		return -1;
-	}
-
 	cur_offset = (const char *)dir - (const char *)index->const_mmap_base;
-
 	ret = mailbox_list_index_map_area(index, cur_offset, dir->dir_size);
 	if (ret <= 0) {
 		if (ret < 0)
@@ -483,6 +463,31 @@ int mailbox_list_index_get_dir(struct ma
 	*offset = cur_offset;
 	*dir_r = dir;
 	return 0;
+}
+
+static int mailbox_list_record_cmp(const void *_key, const void *_rec)
+{
+	const struct mailbox_list_index_lookup_key *key = _key;
+	const struct mailbox_list_record *rec = _rec;
+	int ret;
+
+	if (key->name_hash < rec->name_hash)
+		return -1;
+	if (key->name_hash > rec->name_hash)
+		return 1;
+
+	T_BEGIN {
+		const char *name;
+
+		if (mailbox_list_get_name(key->index, unsafe_data_stack_pool,
+					  rec, &name) < 0) {
+			*key->failed = TRUE;
+			ret = 0;
+		} else {
+			ret = strcmp(key->name, name);
+		}
+	} T_END;
+	return ret;
 }
 
 int mailbox_list_index_dir_lookup_rec(struct mailbox_list_index *index,
@@ -578,7 +583,8 @@ int mailbox_list_index_view_init(struct 
 	const struct mail_index_header *mail_hdr;
 
 	mail_hdr = mail_view != NULL ? mail_index_get_header(mail_view) : NULL;
-	if (mail_hdr != NULL && index->hdr != NULL &&
+	if (mail_hdr != NULL && mail_hdr->uid_validity != 0 &&
+	    index->hdr != NULL &&
 	    mail_hdr->uid_validity != index->hdr->uid_validity) {
 		mail_index_set_error(index->mail_index,
 			"uid_validity mismatch in file %s: %u != %u",


More information about the dovecot-cvs mailing list