Mercurial > dovecot > original-hg > dovecot-1.2
changeset 9480:e5d38150be58 HEAD
mail_index_update_header_ext(): Couldn't handle >=64k headers.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 19 Nov 2009 18:52:54 -0500 |
parents | 3e1ca490dde0 |
children | ee1782019a60 |
files | src/lib-index/mail-index-sync-ext.c src/lib-index/mail-index-sync-private.h src/lib-index/mail-index-sync-update.c src/lib-index/mail-transaction-log-append.c src/lib-index/mail-transaction-log.h src/util/logview.c |
diffstat | 6 files changed, 74 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mail-index-sync-ext.c Thu Nov 19 18:31:14 2009 -0500 +++ b/src/lib-index/mail-index-sync-ext.c Thu Nov 19 18:52:54 2009 -0500 @@ -606,9 +606,9 @@ return 1; } -int -mail_index_sync_ext_hdr_update(struct mail_index_sync_map_ctx *ctx, - const struct mail_transaction_ext_hdr_update *u) +int mail_index_sync_ext_hdr_update(struct mail_index_sync_map_ctx *ctx, + uint32_t offset, uint32_t size, + const void *data) { struct mail_index_map *map = ctx->view->map; const struct mail_index_ext *ext; @@ -622,10 +622,9 @@ return 1; ext = array_idx(&map->extensions, ctx->cur_ext_map_idx); - i_assert(ext->hdr_offset + u->offset + u->size <= map->hdr.header_size); + i_assert(ext->hdr_offset + offset + size <= map->hdr.header_size); - buffer_write(map->hdr_copy_buf, ext->hdr_offset + u->offset, - u + 1, u->size); + buffer_write(map->hdr_copy_buf, ext->hdr_offset + offset, data, size); map->hdr_base = map->hdr_copy_buf->data; if (ext->index_idx == ctx->view->index->modseq_ext_id)
--- a/src/lib-index/mail-index-sync-private.h Thu Nov 19 18:31:14 2009 -0500 +++ b/src/lib-index/mail-index-sync-private.h Thu Nov 19 18:52:54 2009 -0500 @@ -76,9 +76,9 @@ const struct mail_transaction_ext_intro *u); int mail_index_sync_ext_reset(struct mail_index_sync_map_ctx *ctx, const struct mail_transaction_ext_reset *u); -int -mail_index_sync_ext_hdr_update(struct mail_index_sync_map_ctx *ctx, - const struct mail_transaction_ext_hdr_update *u); +int mail_index_sync_ext_hdr_update(struct mail_index_sync_map_ctx *ctx, + uint32_t offset, uint32_t size, + const void *data); int mail_index_sync_ext_rec_update(struct mail_index_sync_map_ctx *ctx, const struct mail_transaction_ext_rec_update *u);
--- a/src/lib-index/mail-index-sync-update.c Thu Nov 19 18:31:14 2009 -0500 +++ b/src/lib-index/mail-index-sync-update.c Thu Nov 19 18:52:54 2009 -0500 @@ -626,7 +626,34 @@ break; } - ret = mail_index_sync_ext_hdr_update(ctx, rec); + ret = mail_index_sync_ext_hdr_update(ctx, rec->offset, + rec->size, rec + 1); + if (ret <= 0) + break; + + i += sizeof(*rec) + rec->size; + if ((i % 4) != 0) + i += 4 - (i % 4); + } + break; + } + case MAIL_TRANSACTION_EXT_HDR_UPDATE32: { + const struct mail_transaction_ext_hdr_update32 *rec = data; + unsigned int i; + + for (i = 0; i < hdr->size; ) { + rec = CONST_PTR_OFFSET(data, i); + + if (i + sizeof(*rec) > hdr->size || + i + sizeof(*rec) + rec->size > hdr->size) { + mail_index_sync_set_corrupted(ctx, + "ext hdr update: invalid record size"); + ret = -1; + break; + } + + ret = mail_index_sync_ext_hdr_update(ctx, rec->offset, + rec->size, rec + 1); if (ret <= 0) break;
--- a/src/lib-index/mail-transaction-log-append.c Thu Nov 19 18:31:14 2009 -0500 +++ b/src/lib-index/mail-transaction-log-append.c Thu Nov 19 18:52:54 2009 -0500 @@ -311,10 +311,12 @@ buffer_t *buf; const unsigned char *data, *mask; struct mail_transaction_ext_hdr_update u; + struct mail_transaction_ext_hdr_update u32; size_t offset; - bool started = FALSE; + bool started = FALSE, use_32 = hdr->alloc_size >= 65536; memset(&u, 0, sizeof(u)); + memset(&u32, 0, sizeof(u32)); data = hdr->data; mask = hdr->mask; @@ -323,21 +325,29 @@ for (offset = 0; offset <= hdr->alloc_size; offset++) { if (offset < hdr->alloc_size && mask[offset] != 0) { if (!started) { - u.offset = offset; + u32.offset = offset; started = TRUE; } } else { if (started) { - u.size = offset - u.offset; - buffer_append(buf, &u, sizeof(u)); - buffer_append(buf, data + u.offset, u.size); + u32.size = offset - u32.offset; + if (use_32) + buffer_append(buf, &u32, sizeof(u32)); + else { + u.offset = u32.offset; + u.size = u32.size; + buffer_append(buf, &u, sizeof(u)); + } + buffer_append(buf, data + u32.offset, u32.size); started = FALSE; } } } if (buf->used % 4 != 0) buffer_append_zero(buf, 4 - buf->used % 4); - log_append_buffer(ctx, buf, NULL, MAIL_TRANSACTION_EXT_HDR_UPDATE); + log_append_buffer(ctx, buf, NULL, + use_32 ? MAIL_TRANSACTION_EXT_HDR_UPDATE32 : + MAIL_TRANSACTION_EXT_HDR_UPDATE); } static void
--- a/src/lib-index/mail-transaction-log.h Thu Nov 19 18:31:14 2009 -0500 +++ b/src/lib-index/mail-transaction-log.h Thu Nov 19 18:52:54 2009 -0500 @@ -41,12 +41,14 @@ MAIL_TRANSACTION_EXPUNGE_GUID = 0x00002000, MAIL_TRANSACTION_UID_UPDATE = 0x00004000, MAIL_TRANSACTION_MODSEQ_UPDATE = 0x00008000, + MAIL_TRANSACTION_EXT_HDR_UPDATE32 = 0x00010000, MAIL_TRANSACTION_TYPE_MASK = 0x0000ffff, #define MAIL_TRANSACTION_EXT_MASK \ (MAIL_TRANSACTION_EXT_INTRO | MAIL_TRANSACTION_EXT_RESET | \ - MAIL_TRANSACTION_EXT_HDR_UPDATE | MAIL_TRANSACTION_EXT_REC_UPDATE) + MAIL_TRANSACTION_EXT_HDR_UPDATE | MAIL_TRANSACTION_EXT_HDR_UPDATE32 | \ + MAIL_TRANSACTION_EXT_REC_UPDATE) /* since we'll expunge mails based on data read from transaction log, try to avoid the possibility of corrupted transaction log expunging @@ -141,6 +143,14 @@ uint16_t size; /* unsigned char data[]; */ }; +/* this _update32 version should have been the only ext_hdr_update, + but since 16bit integers were originally used for now we'll just use this + only when actually needed to be backwards compatible. */ +struct mail_transaction_ext_hdr_update32 { + uint32_t offset; + uint32_t size; + /* unsigned char data[]; */ +}; struct mail_transaction_ext_rec_update { uint32_t uid;
--- a/src/util/logview.c Thu Nov 19 18:31:14 2009 -0500 +++ b/src/util/logview.c Thu Nov 19 18:52:54 2009 -0500 @@ -93,6 +93,9 @@ case MAIL_TRANSACTION_EXT_HDR_UPDATE: name = "ext-hdr"; break; + case MAIL_TRANSACTION_EXT_HDR_UPDATE32: + name = "ext-hdr32"; + break; case MAIL_TRANSACTION_EXT_REC_UPDATE: name = "ext-rec"; break; @@ -309,6 +312,14 @@ printf("\n"); break; } + case MAIL_TRANSACTION_EXT_HDR_UPDATE32: { + const struct mail_transaction_ext_hdr_update32 *u = data; + + printf(" - offset = %u, size = %u: ", u->offset, u->size); + print_data(u + 1, u->size); + printf("\n"); + break; + } case MAIL_TRANSACTION_EXT_REC_UPDATE: { const struct mail_transaction_ext_rec_update *rec = data, *end; size_t record_size;