From 6df4f4432752b9857db4dcb03aa48319fe8049f1 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Fri, 17 Aug 2018 14:39:41 +0300 Subject: [PATCH] lib-storage: Fix NUL handling in mail_get_first_header*(), mail_get_headers*() These functions return NUL-terminated values, so they got truncated whenever a header value contained a NUL. Fix this by converting NULs to unicode replacement characters in the output. --- src/lib-storage/index/index-mail-headers.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/lib-storage/index/index-mail-headers.c b/src/lib-storage/index/index-mail-headers.c index e51aa43ad3..04c6a7a2a8 100644 --- a/src/lib-storage/index/index-mail-headers.c +++ b/src/lib-storage/index/index-mail-headers.c @@ -613,8 +613,9 @@ index_mail_get_parsed_header(struct index_mail *mail, unsigned int field_idx) if (skip_header(&value_start, value_end - value_start)) { if (value_start != value_end && value_end[-1] == '\n') value_end--; - value = p_strndup(mail->mail.data_pool, value_start, - value_end - value_start); + value = message_header_strdup(mail->mail.data_pool, + value_start, + value_end - value_start); array_append(&header_values, &value, 1); } } @@ -630,7 +631,7 @@ index_mail_get_raw_headers(struct index_mail *mail, const char *field, struct mail *_mail = &mail->mail.mail; const char *headers[2], *value; struct mailbox_header_lookup_ctx *headers_ctx; - unsigned char *data; + const unsigned char *data; unsigned int field_idx; string_t *dest; size_t i, len, len2; @@ -642,7 +643,7 @@ index_mail_get_raw_headers(struct index_mail *mail, const char *field, field_idx = get_header_field_idx(_mail->box, field, MAIL_CACHE_DECISION_TEMP); - dest = str_new(mail->mail.data_pool, 128); + dest = t_str_new(128); if (mail_cache_lookup_headers(_mail->transaction->cache_view, dest, _mail->seq, &field_idx, 1) <= 0) { /* not in cache / error - first see if it's already parsed */ @@ -679,7 +680,7 @@ index_mail_get_raw_headers(struct index_mail *mail, const char *field, return 0; } _mail->transaction->stats.cache_hit_count++; - data = buffer_get_modifiable_data(dest, &len); + data = buffer_get_data(dest, &len); if (len == 0) { /* cached as nonexistent. */ @@ -697,8 +698,8 @@ index_mail_get_raw_headers(struct index_mail *mail, const char *field, /* @UNSAFE */ len2 = get_header_size(dest, i); - data[i + len2] = '\0'; - value = (const char *)data + i; + value = message_header_strdup(mail->mail.data_pool, + data + i, len2); i += len2 + 1; array_append(&header_values, &value, 1);