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;