Mercurial > dovecot > core-2.2
changeset 20323:07f21d0fb517
lib-index: Fixes to handling resized records.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Tue, 14 Jun 2016 01:14:13 +0300 |
parents | e1184fa94529 |
children | 97fa8fcdffd4 |
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-index-transaction-export.c |
diffstat | 4 files changed, 17 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mail-index-sync-ext.c Mon Jun 13 20:16:14 2016 +0300 +++ b/src/lib-index/mail-index-sync-ext.c Tue Jun 14 01:14:13 2016 +0300 @@ -478,6 +478,7 @@ intro is corrupted */ ctx->cur_ext_map_idx = (uint32_t)-2; ctx->cur_ext_ignore = TRUE; + ctx->cur_ext_record_size = 0; if (u->ext_id != (uint32_t)-1 && (!array_is_created(&map->extensions) || @@ -537,6 +538,7 @@ return -1; } + ctx->cur_ext_record_size = u->record_size; if (ext != NULL) { /* exists already */ if (u->reset_id == ext->reset_id) { @@ -675,7 +677,7 @@ return 1; ext = array_idx(&view->map->extensions, ctx->cur_ext_map_idx); - i_assert(ext->record_offset + ext->record_size <= + i_assert(ext->record_offset + ctx->cur_ext_record_size <= view->map->hdr.record_size); rec = MAIL_INDEX_REC_AT_SEQ(view->map, seq); @@ -696,7 +698,11 @@ } /* @UNSAFE */ - memcpy(old_data, u + 1, ext->record_size); + memcpy(old_data, u + 1, ctx->cur_ext_record_size); + if (ctx->cur_ext_record_size < ext->record_size) { + memset(PTR_OFFSET(old_data, ctx->cur_ext_record_size), 0, + ext->record_size - ctx->cur_ext_record_size); + } return 1; } @@ -724,7 +730,7 @@ return 1; ext = array_idx(&view->map->extensions, ctx->cur_ext_map_idx); - i_assert(ext->record_offset + ext->record_size <= + i_assert(ext->record_offset + ctx->cur_ext_record_size <= view->map->hdr.record_size); rec = MAIL_INDEX_REC_AT_SEQ(view->map, seq); @@ -732,8 +738,8 @@ min_value = u->diff >= 0 ? 0 : (uint64_t)(-(int64_t)u->diff); - max_value = ext->record_size == 8 ? (uint64_t)-1 : - ((uint64_t)1 << (ext->record_size*8)) - 1; + max_value = ctx->cur_ext_record_size == 8 ? (uint64_t)-1 : + ((uint64_t)1 << (ctx->cur_ext_record_size*8)) - 1; if (u->diff <= 0) { /* skip */ } else if (max_value >= (uint32_t)u->diff) { @@ -745,7 +751,7 @@ return -1; } - switch (ext->record_size) { + switch (ctx->cur_ext_record_size) { case 1: { uint8_t *num = data; @@ -778,7 +784,7 @@ default: mail_index_sync_set_corrupted(ctx, "Extension record inc with invalid size=%u", - ext->record_size); + ctx->cur_ext_record_size); return -1; } if (orig_num < min_value) {
--- a/src/lib-index/mail-index-sync-private.h Mon Jun 13 20:16:14 2016 +0300 +++ b/src/lib-index/mail-index-sync-private.h Tue Jun 14 01:14:13 2016 +0300 @@ -27,6 +27,7 @@ struct mail_index_view *view; struct mail_index_modseq_sync *modseq_ctx; uint32_t cur_ext_map_idx; + uint32_t cur_ext_record_size; uint32_t ext_intro_seq; uoff_t ext_intro_offset, ext_intro_end_offset;
--- a/src/lib-index/mail-index-sync-update.c Mon Jun 13 20:16:14 2016 +0300 +++ b/src/lib-index/mail-index-sync-update.c Tue Jun 14 01:14:13 2016 +0300 @@ -712,7 +712,6 @@ } case MAIL_TRANSACTION_EXT_REC_UPDATE: { const struct mail_transaction_ext_rec_update *rec; - const struct mail_index_ext *ext; unsigned int i, record_size; if (ctx->cur_ext_map_idx == (uint32_t)-1) { @@ -728,10 +727,8 @@ break; } - ext = array_idx(&ctx->view->map->extensions, - ctx->cur_ext_map_idx); /* the record is padded to 32bits in the transaction log */ - record_size = (sizeof(*rec) + ext->record_size + 3) & ~3; + record_size = (sizeof(*rec) + ctx->cur_ext_record_size + 3) & ~3; for (i = 0; i < hdr->size; i += record_size) { rec = CONST_PTR_OFFSET(data, i);
--- a/src/lib-index/mail-index-transaction-export.c Mon Jun 13 20:16:14 2016 +0300 +++ b/src/lib-index/mail-index-transaction-export.c Tue Jun 14 01:14:13 2016 +0300 @@ -138,16 +138,14 @@ /* generate a new intro structure */ intro = buffer_append_space_unsafe(buf, sizeof(*intro)); intro->ext_id = idx; + intro->record_size = rext->record_size; + intro->record_align = rext->record_align; if (idx == (uint32_t)-1) { intro->hdr_size = rext->hdr_size; - intro->record_size = rext->record_size; - intro->record_align = rext->record_align; intro->name_size = strlen(rext->name); } else { ext = array_idx(&t->view->index->map->extensions, idx); intro->hdr_size = ext->hdr_size; - intro->record_size = ext->record_size; - intro->record_align = ext->record_align; intro->name_size = 0; } intro->flags = MAIL_TRANSACTION_EXT_INTRO_FLAG_NO_SHRINK;