]> dgit.raspbian.org Git - dovecot.git/commitdiff
[PATCH 04/14] lib-mail: message-parser-from-parts: Enforce 50 MB all-headers-max...
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Thu, 16 Apr 2026 20:38:02 +0000 (22:38 +0200)
committerNoah Meyerhans <noahm@debian.org>
Wed, 16 Sep 2026 19:06:35 +0000 (15:06 -0400)
The preparsed (from-parts) header parser was not tracking
all_headers_total_size and never called message_parse_header_lower_limit(),
so the cumulative 50 MB header size limit was never applied when re-parsing
a message using cached part structure.

Fix by mirroring the same tracking that message-parser.c does in its
parse_next_header_block(): update all_headers_total_size for each parsed
header line, and call message_parse_header_lower_limit() with the remaining
budget when initialising the per-part header parser.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Gbp-Pq: Name 0004-lib-mail-message-parser-from-parts-Enforce-50-MB-all.patch

src/lib-mail/message-parser-from-parts.c

index 867a916c1ce83b072f3c0a886571cd22a61aa156..fb75dc7148804564dc833ae5c85d294e18e3307b 100644 (file)
@@ -303,6 +303,11 @@ static int preparsed_parse_next_header(struct message_parser_ctx *ctx,
        }
 
        if (hdr != NULL) {
+               if (!hdr->continues) {
+                       ctx->all_headers_total_size += hdr->name_len;
+                       ctx->all_headers_total_size += hdr->middle_len;
+               }
+               ctx->all_headers_total_size += hdr->value_len;
                block_r->hdr = hdr;
                block_r->size = 0;
                return 1;
@@ -344,6 +349,11 @@ static int preparsed_parse_next_header_init(struct message_parser_ctx *ctx,
                message_parse_header_init(hdr_input, NULL, ctx->hdr_flags);
        i_stream_unref(&hdr_input);
 
+       size_t headers_available =
+               ctx->all_headers_max_size > ctx->all_headers_total_size ?
+               ctx->all_headers_max_size - ctx->all_headers_total_size : 0;
+       message_parse_header_lower_limit(ctx->hdr_parser_ctx, headers_available);
+
        ctx->parse_next_block = preparsed_parse_next_header;
        return preparsed_parse_next_header(ctx, block_r);
 }