]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Minor changes to mailbox list indexing code. Still disabled/non-working.
authorTimo Sirainen <tss@iki.fi>
Tue, 10 Feb 2009 17:46:14 +0000 (12:46 -0500)
committerTimo Sirainen <tss@iki.fi>
Tue, 10 Feb 2009 17:46:14 +0000 (12:46 -0500)
--HG--
branch : HEAD

src/lib-index/mailbox-list-index-private.h
src/lib-index/mailbox-list-index.c

index 6a59c6155a9158109d2d7f01336a7fd4613a9d73..0d98721f999cdb4ced6c4ae650b29767b3f46bcd 100644 (file)
@@ -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;
 };
index 52ca1ab9989dcbe832f52a05b647152bf2a0c5f2..97e85bcf11f5a577ebbc26f3ef3dedc027e9865b 100644 (file)
@@ -388,8 +388,9 @@ mailbox_list_get_name(struct mailbox_list_index *index, pool_t pool,
        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_list_index *index, pool_t pool,
           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);
-       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)
+       if (*name_r == '\0') {
+               mailbox_list_index_set_corrupted(index, "Empty mailbox name");
                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;
+       }
+       return 0;
 }
 
 int mailbox_list_index_get_dir(struct mailbox_list_index_view *view,
@@ -457,6 +437,12 @@ int mailbox_list_index_get_dir(struct mailbox_list_index_view *view,
                        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 mailbox_list_index_view *view,
                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)
@@ -485,6 +465,31 @@ int mailbox_list_index_get_dir(struct mailbox_list_index_view *view,
        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,
                                      const struct mailbox_list_dir_record *dir,
                                      const char *name,
@@ -578,7 +583,8 @@ int mailbox_list_index_view_init(struct mailbox_list_index *index,
        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",