dovecot-1.2: If we detect cached header is corrupted while unfol...
dovecot at dovecot.org
dovecot at dovecot.org
Thu Feb 19 20:08:57 EET 2009
details: http://hg.dovecot.org/dovecot-1.2/rev/13e1c379ab63
changeset: 8749:13e1c379ab63
user: Timo Sirainen <tss at iki.fi>
date: Thu Feb 19 13:08:50 2009 -0500
description:
If we detect cached header is corrupted while unfolding it, mark the cache corrupted.
diffstat:
1 file changed, 57 insertions(+), 27 deletions(-)
src/lib-storage/index/index-mail-headers.c | 84 +++++++++++++++++++---------
diffs (143 lines):
diff -r b39e85979c6a -r 13e1c379ab63 src/lib-storage/index/index-mail-headers.c
--- a/src/lib-storage/index/index-mail-headers.c Fri Feb 13 17:44:00 2009 -0500
+++ b/src/lib-storage/index/index-mail-headers.c Thu Feb 19 13:08:50 2009 -0500
@@ -650,8 +650,9 @@ index_mail_get_raw_headers(struct index_
return 0;
}
-static const char *unfold_header(pool_t pool, const char *str)
-{
+static int unfold_header(pool_t pool, const char **_str)
+{
+ const char *str = *_str;
char *new_str;
unsigned int i, j;
@@ -660,7 +661,7 @@ static const char *unfold_header(pool_t
break;
}
if (str[i] == '\0')
- return str;
+ return 0;
/* @UNSAFE */
new_str = p_malloc(pool, i + strlen(str+i) + 1);
@@ -671,19 +672,25 @@ static const char *unfold_header(pool_t
i++;
if (str[i] == '\0')
break;
- i_assert(str[i] == ' ' || str[i] == '\t');
+
+ if (str[i] != ' ' && str[i] != '\t') {
+ /* corrupted */
+ return -1;
+ }
} else {
new_str[j++] = str[i];
}
}
new_str[j] = '\0';
- return new_str;
-}
-
-static const char *const *
-index_mail_headers_decode(struct index_mail *mail, const char *const *list,
+ *_str = new_str;
+ return 0;
+}
+
+static int
+index_mail_headers_decode(struct index_mail *mail, const char *const **_list,
unsigned int max_count)
{
+ const char *const *list = *_list;
const char **decoded_list, *input;
unsigned int i, count;
string_t *str;
@@ -700,28 +707,39 @@ index_mail_headers_decode(struct index_m
if (message_header_decode_utf8((const unsigned char *)input,
strlen(list[i]), str, FALSE))
input = str_c(str);
- input = unfold_header(mail->data_pool, input);
+ if (unfold_header(mail->data_pool, &input) < 0)
+ return -1;
if (input == str->data)
input = p_strdup(mail->data_pool, input);
decoded_list[i] = input;
}
- return decoded_list;
+ *_list = decoded_list;
+ return 0;
}
int index_mail_get_headers(struct mail *_mail, const char *field,
bool decode_to_utf8, const char *const **value_r)
{
struct index_mail *mail = (struct index_mail *)_mail;
-
- if (index_mail_get_raw_headers(mail, field, value_r) < 0)
- return -1;
- if (!decode_to_utf8 || **value_r == NULL)
- return 0;
-
- T_BEGIN {
- *value_r = index_mail_headers_decode(mail, *value_r, -1U);
- } T_END;
- return 0;
+ int ret, i;
+
+ for (i = 0; i < 2; i++) {
+ if (index_mail_get_raw_headers(mail, field, value_r) < 0)
+ return -1;
+ if (!decode_to_utf8 || **value_r == NULL)
+ return 0;
+
+ T_BEGIN {
+ ret = index_mail_headers_decode(mail, value_r, -1U);
+ } T_END;
+
+ if (ret < 0) {
+ mail_cache_set_corrupted(mail->ibox->cache,
+ "Broken header %s for mail UID %u",
+ field, _mail->uid);
+ }
+ }
+ return ret;
}
int index_mail_get_first_header(struct mail *_mail, const char *field,
@@ -729,16 +747,28 @@ int index_mail_get_first_header(struct m
{
struct index_mail *mail = (struct index_mail *)_mail;
const char *const *list;
-
- if (index_mail_get_raw_headers(mail, field, &list) < 0)
- return -1;
- if (decode_to_utf8 && list[0] != NULL) {
+ int ret, i;
+
+ for (i = 0; i < 2; i++) {
+ if (index_mail_get_raw_headers(mail, field, &list) < 0)
+ return -1;
+ if (!decode_to_utf8 || list[0] == NULL) {
+ ret = 0;
+ break;
+ }
+
T_BEGIN {
- list = index_mail_headers_decode(mail, list, 1);
+ ret = index_mail_headers_decode(mail, &list, 1);
} T_END;
+
+ if (ret < 0) {
+ mail_cache_set_corrupted(mail->ibox->cache,
+ "Broken header %s for mail UID %u",
+ field, _mail->uid);
+ }
}
*value_r = list[0];
- return list[0] != NULL ? 1 : 0;
+ return ret < 0 ? -1 : (list[0] != NULL ? 1 : 0);
}
static void header_cache_callback(struct message_header_line *hdr,
More information about the dovecot-cvs
mailing list