From: Timo Sirainen Date: Tue, 21 Oct 2003 03:14:44 +0000 (+0300) Subject: Some cleanups and extra checks to detect if header names list gets X-Git-Tag: 1.1.alpha1~4276 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b3a53020f8f629fa8b0bc4be4ad5660d9701f22d;p=thirdparty%2Fdovecot%2Fcore.git Some cleanups and extra checks to detect if header names list gets duplicated (can happen, why?..) --HG-- branch : HEAD --- diff --git a/src/lib-index/mail-cache.c b/src/lib-index/mail-cache.c index 66e8de4798..d1de10bd1b 100644 --- a/src/lib-index/mail-cache.c +++ b/src/lib-index/mail-cache.c @@ -1325,21 +1325,15 @@ const char *const *mail_cache_get_header_fields(struct mail_cache *cache, return cache->split_headers[idx]; } -int mail_cache_set_header_fields(struct mail_cache_transaction_ctx *ctx, - unsigned int idx, const char *const headers[]) +static const char *write_header_string(const char *const headers[], + size_t *size_r) { - struct mail_cache *cache = ctx->cache; - uint32_t offset, update_offset, size; buffer_t *buffer; - - i_assert(idx < MAIL_CACHE_HEADERS_COUNT); - i_assert(idx >= ctx->next_unused_header_lowwater); - i_assert(offset_to_uint32(cache->header->header_offsets[idx]) == 0); - - t_push(); + size_t size; buffer = buffer_create_dynamic(pool_datastack_create(), 512, (size_t)-1); + while (*headers != NULL) { if (buffer_get_used_size(buffer) != 0) buffer_append(buffer, "\n", 1); @@ -1353,11 +1347,32 @@ int mail_cache_set_header_fields(struct mail_cache_transaction_ctx *ctx, buffer_append(buffer, null4, 4 - (size & 3)); size += 4 - (size & 3); } + *size_r = size; + return buffer_get_data(buffer, NULL); +} + +int mail_cache_set_header_fields(struct mail_cache_transaction_ctx *ctx, + unsigned int idx, const char *const headers[]) +{ + struct mail_cache *cache = ctx->cache; + uint32_t offset, update_offset, size; + const char *header_str; + + i_assert(idx < MAIL_CACHE_HEADERS_COUNT); + i_assert(idx >= ctx->next_unused_header_lowwater); + i_assert(offset_to_uint32(cache->header->header_offsets[idx]) == 0); + + t_push(); + + header_str = write_header_string(headers, &size); + i_assert(idx == 0 || + strcmp(mail_cache_get_header_fields_str(cache, idx-1), + header_str) != 0); offset = mail_cache_append_space(ctx, size + sizeof(uint32_t)); if (offset != 0) { memcpy((char *) cache->mmap_base + offset + sizeof(uint32_t), - buffer_get_data(buffer, NULL), size); + header_str, size); size = uint32_to_nbo(size); memcpy((char *) cache->mmap_base + offset, @@ -1365,8 +1380,7 @@ int mail_cache_set_header_fields(struct mail_cache_transaction_ctx *ctx, /* update cached headers */ cache->split_offsets[idx] = cache->header->header_offsets[idx]; - cache->split_headers[idx] = - split_header(cache, buffer_get_data(buffer, NULL)); + cache->split_headers[idx] = split_header(cache, header_str); /* mark used-bit to be updated later. not really needed for read-safety, but if transaction get rolled back we can't let diff --git a/src/lib-storage/index/index-mail-headers.c b/src/lib-storage/index/index-mail-headers.c index b893e30b24..9dfbb03aee 100644 --- a/src/lib-storage/index/index-mail-headers.c +++ b/src/lib-storage/index/index-mail-headers.c @@ -147,6 +147,7 @@ static int find_wanted_headers(struct mail_cache *cache, if (wanted_headers == NULL || *wanted_headers == NULL) return -1; + t_push(); wanted_headers = sort_array(wanted_headers); ret = -1; @@ -167,11 +168,12 @@ static int find_wanted_headers(struct mail_cache *cache, } if (*tmp != NULL) - return ret; + break; /* find the minimum matching header number */ ret = i; } + t_pop(); return ret; } @@ -756,7 +758,11 @@ void index_mail_headers_close(struct index_mail *mail) idx = find_wanted_headers(mail->ibox->index->cache, headers); if (idx >= 0) { /* all headers found */ - i_assert(idx == mail->data.header_save_idx); + if (idx != mail->data.header_save_idx) { + mail_cache_set_corrupted(mail->ibox->index->cache, + "Duplicated header names list (%d and %d)", + idx, mail->data.header_save_idx); + } } else { /* there's some new headers */ idx = find_unused_header_idx(mail->ibox->index->cache);