]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-mail: message-decoder - Add flag to skip RFC 2047 decoding for address headers
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Fri, 17 Apr 2026 19:32:23 +0000 (19:32 +0000)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Fri, 1 May 2026 08:14:34 +0000 (08:14 +0000)
Add MESSAGE_DECODER_FLAG_RAW_ADDRESS_HEADERS. When set, address headers
(From, To, Cc, etc.) are passed through with their raw bytes intact
instead of having encoded-words decoded to UTF-8. This lets callers
feed the raw value to message_address_parse() so that decoded display
name characters like '(' or '[' are not reinterpreted as RFC 5322
comments or other specials during address parsing.

src/lib-mail/message-decoder.c
src/lib-mail/message-decoder.h

index d1b6591f5d426bee091baf36885254e0c577816d..f8fb04d0cbf746b79348673e99323d58c3b187fc 100644 (file)
@@ -11,6 +11,7 @@
 #include "rfc2231-parser.h"
 #include "message-parser.h"
 #include "message-header-decode.h"
+#include "message-address.h"
 #include "message-decoder.h"
 
 struct message_decoder_context {
@@ -180,8 +181,17 @@ static bool message_decode_header(struct message_decoder_context *ctx,
        } T_END;
 
        buffer_set_used_size(ctx->buf, 0);
-       message_header_decode_utf8(hdr->full_value, hdr->full_value_len,
-                                  ctx->buf, ctx->normalizer);
+       if ((ctx->flags & MESSAGE_DECODER_FLAG_RAW_ADDRESS_HEADERS) != 0 &&
+           message_header_is_address(hdr->name)) {
+               /* Pass the raw header value through unchanged so the caller
+                  can run message_address_parse() on the original bytes
+                  (encoded-words intact) rather than on a string that may
+                  contain RFC 5322 special characters after decoding. */
+               buffer_append(ctx->buf, hdr->full_value, hdr->full_value_len);
+       } else {
+               message_header_decode_utf8(hdr->full_value, hdr->full_value_len,
+                                          ctx->buf, ctx->normalizer);
+       }
        value_len = ctx->buf->used;
 
        if (ctx->normalizer != NULL) {
index 9928ae664fb49a496aaf6abdfcb05cbdfab868f8..292e2d1151cf104611e9ac3a0723d87278d3b519 100644 (file)
@@ -15,7 +15,12 @@ enum message_cte {
 
 enum message_decoder_flags {
        /* Return binary MIME parts as-is without any conversion. */
-       MESSAGE_DECODER_FLAG_RETURN_BINARY      = 0x02
+       MESSAGE_DECODER_FLAG_RETURN_BINARY              = 0x02,
+       /* Don't decode RFC 2047 encoded-words in address headers (From, To,
+          Cc, etc.). The raw header value is passed through unchanged so the
+          caller can feed it to message_address_parse() and then decode the
+          normalised result itself. */
+       MESSAGE_DECODER_FLAG_RAW_ADDRESS_HEADERS        = 0x04
 };
 
 struct message_block;