]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Fix NUL handling in mail_get_first_header*(), mail_get_headers*()
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Fri, 17 Aug 2018 11:39:41 +0000 (14:39 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 30 Aug 2018 08:24:43 +0000 (11:24 +0300)
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

index e51aa43ad3e4575349718ab164c6edddab382c07..04c6a7a2a8109bc64fbb0d8e3209c1f8bec96ce5 100644 (file)
@@ -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);