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