Mercurial > dovecot > core-2.2
changeset 10380:8b3c802556a9 HEAD
mail_index_update_header_ext(): Couldn't handle >=64k headers.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 19 Nov 2009 18:45:21 -0500 |
parents | 7ad38188c36b |
children | b12f7da461e3 |
files | src/doveadm/doveadm-dump-log.c 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-index-transaction-export.c src/lib-index/mail-transaction-log.h |
diffstat | 6 files changed, 72 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/src/doveadm/doveadm-dump-log.c Thu Nov 19 06:32:54 2009 +0000 +++ b/src/doveadm/doveadm-dump-log.c Thu Nov 19 18:45:21 2009 -0500 @@ -88,6 +88,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; @@ -323,6 +326,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;
--- a/src/lib-index/mail-index-sync-ext.c Thu Nov 19 06:32:54 2009 +0000 +++ b/src/lib-index/mail-index-sync-ext.c Thu Nov 19 18:45:21 2009 -0500 @@ -603,9 +603,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; @@ -619,10 +619,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 06:32:54 2009 +0000 +++ b/src/lib-index/mail-index-sync-private.h Thu Nov 19 18:45:21 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 06:32:54 2009 +0000 +++ b/src/lib-index/mail-index-sync-update.c Thu Nov 19 18:45:21 2009 -0500 @@ -687,7 +687,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-index-transaction-export.c Thu Nov 19 06:32:54 2009 +0000 +++ b/src/lib-index/mail-index-transaction-export.c Thu Nov 19 18:45:21 2009 -0500 @@ -130,10 +130,12 @@ buffer_t *buf; const unsigned char *data, *mask; struct mail_transaction_ext_hdr_update u; - uint16_t offset; - bool started = FALSE; + struct mail_transaction_ext_hdr_update32 u32; + size_t offset; + 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; @@ -142,21 +144,28 @@ 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, MAIL_TRANSACTION_EXT_HDR_UPDATE); + log_append_buffer(ctx, buf, 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 06:32:54 2009 +0000 +++ b/src/lib-index/mail-transaction-log.h Thu Nov 19 18:45:21 2009 -0500 @@ -41,6 +41,7 @@ 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, @@ -141,6 +142,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;