diff src/lib-index/mail-cache-fields.c @ 4722:b0cf3e4d6c96 HEAD

If cache file contains broken field type or decision type mark the cache corrupted instead of assert-crashing later.
author Timo Sirainen <tss@iki.fi>
date Thu, 02 Nov 2006 19:49:27 +0200
parents 35d9433de1ca
children 7ebe0593f488
line wrap: on
line diff
--- a/src/lib-index/mail-cache-fields.c	Thu Nov 02 19:26:31 2006 +0200
+++ b/src/lib-index/mail-cache-fields.c	Thu Nov 02 19:49:27 2006 +0200
@@ -21,12 +21,27 @@
 	case MAIL_CACHE_FIELD_STRING:
 	case MAIL_CACHE_FIELD_HEADER:
 		return FALSE;
+
+	case MAIL_CACHE_FIELD_COUNT:
+		break;
 	}
 
 	i_unreached();
 	return FALSE;
 }
 
+static bool field_decision_is_valid(enum mail_cache_decision_type type)
+{
+	switch (type & ~MAIL_CACHE_DECISION_FORCED) {
+	case MAIL_CACHE_DECISION_NO:
+	case MAIL_CACHE_DECISION_TEMP:
+	case MAIL_CACHE_DECISION_YES:
+		return TRUE;
+	default:
+		return FALSE;
+	}
+}
+
 static int field_type_verify(struct mail_cache *cache, unsigned int idx,
 			     enum mail_cache_field_type type, unsigned int size)
 {
@@ -58,6 +73,8 @@
 	for (i = 0; i < fields_count; i++) {
 		if (hash_lookup_full(cache->field_name_hash, fields[i].name,
 				     &orig_key, &orig_value)) {
+			i_assert(fields[i].type < MAIL_CACHE_FIELD_COUNT);
+
 			fields[i].idx =
 				POINTER_CAST_TO(orig_value, unsigned int);
 			(void)field_type_verify(cache, fields[i].idx,
@@ -263,6 +280,16 @@
 			return -1;
 		}
 
+		if (types[i] > MAIL_CACHE_FIELD_COUNT) {
+			mail_cache_set_corrupted(cache, "field type corrupted");
+			return -1;
+		}
+		if (!field_decision_is_valid(decisions[i])) {
+			mail_cache_set_corrupted(cache,
+				"field decision type corrupted");
+			return -1;
+		}
+
 		if (hash_lookup_full(cache->field_name_hash, names,
 				     &orig_key, &orig_value)) {
 			/* already exists, see if decision can be updated */