From: Timo Sirainen Date: Thu, 16 Apr 2026 20:38:02 +0000 (+0200) Subject: [PATCH 04/14] lib-mail: message-parser-from-parts: Enforce 50 MB all-headers-max... X-Git-Tag: archive/raspbian/1%2.4.1+dfsg1-6+rpi1+deb13u7^2~60 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=c0fe328ed9744aba3b0a79f0843aeb9d365268ec;p=dovecot.git [PATCH 04/14] lib-mail: message-parser-from-parts: Enforce 50 MB all-headers-max-size limit 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 Gbp-Pq: Name 0004-lib-mail-message-parser-from-parts-Enforce-50-MB-all.patch --- diff --git a/src/lib-mail/message-parser-from-parts.c b/src/lib-mail/message-parser-from-parts.c index 867a916..fb75dc7 100644 --- a/src/lib-mail/message-parser-from-parts.c +++ b/src/lib-mail/message-parser-from-parts.c @@ -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); }