From: Timo Sirainen Date: Fri, 17 Apr 2026 13:54:48 +0000 (+0200) Subject: [PATCH 11/14] lib-mail: Introduce struct message_part_data_limits and thread it throu... X-Git-Tag: archive/raspbian/1%2.4.1+dfsg1-6+rpi1+deb13u7^2~53 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=699d93b6856f8df0610a832810218f3363eff352;p=dovecot.git [PATCH 11/14] lib-mail: Introduce struct message_part_data_limits and thread it through parsers Add an empty struct message_part_data_limits and pass it by pointer through message_part_data_parse_from_header() and message_part_envelope_parse_from_header(). No behaviour change: the struct has no fields yet and no limits are applied. Subsequent commits add the individual limit fields and enforcement. Co-Authored-By: Claude Sonnet 4.6 Gbp-Pq: Name 0011-lib-mail-Introduce-struct-message_part_data_limits-a.patch --- diff --git a/src/lib-imap/test-imap-bodystructure.c b/src/lib-imap/test-imap-bodystructure.c index 40c8a8c..abe35ac 100644 --- a/src/lib-imap/test-imap-bodystructure.c +++ b/src/lib-imap/test-imap-bodystructure.c @@ -398,10 +398,11 @@ msg_parse(pool_t pool, const char *message, unsigned int max_nested_mime_parts, input = i_stream_create_from_data(message, strlen(message)); parser = message_parser_init(pool, input, &parser_set); + struct message_part_data_limits limits = MESSAGE_PART_DATA_LIMITS_INIT; while ((ret = message_parser_parse_next_block(parser, &block)) > 0) { if (parse_bodystructure) { message_part_data_parse_from_header(pool, block.part, - block.hdr); + &limits, block.hdr); } } test_assert(ret < 0); diff --git a/src/lib-imap/test-imap-envelope.c b/src/lib-imap/test-imap-envelope.c index c9b92b4..498c6ac 100644 --- a/src/lib-imap/test-imap-envelope.c +++ b/src/lib-imap/test-imap-envelope.c @@ -132,9 +132,11 @@ msg_parse(pool_t pool, const char *message) input = i_stream_create_from_data(message, strlen(message)); parser = message_parser_init(pool, input, &parser_set); + struct message_part_data_limits limits = MESSAGE_PART_DATA_LIMITS_INIT; while ((ret = message_parser_parse_next_block(parser, &block)) > 0) { i_assert(block.part->parent == NULL); - message_part_envelope_parse_from_header(pool, &envlp, block.hdr); + message_part_envelope_parse_from_header(pool, &envlp, &limits, + block.hdr); } test_assert(ret < 0); diff --git a/src/lib-mail/message-part-data.c b/src/lib-mail/message-part-data.c index acd50e5..c302fe5 100644 --- a/src/lib-mail/message-part-data.c +++ b/src/lib-mail/message-part-data.c @@ -173,6 +173,7 @@ envelope_get_field(const char *name) void message_part_envelope_parse_from_header(pool_t pool, struct message_part_envelope **data, + struct message_part_data_limits *limits ATTR_UNUSED, struct message_header_line *hdr) { struct message_part_envelope *d; @@ -480,6 +481,7 @@ parse_content_header(struct message_part_data *data, void message_part_data_parse_from_header(pool_t pool, struct message_part *part, + struct message_part_data_limits *limits, struct message_header_line *hdr) { struct message_part_data *part_data; @@ -525,7 +527,8 @@ void message_part_data_parse_from_header(pool_t pool, if (parent_rfc822) { /* message/rfc822, we need the envelope */ - message_part_envelope_parse_from_header(pool, &part_data->envelope, hdr); + message_part_envelope_parse_from_header(pool, &part_data->envelope, + limits, hdr); } } diff --git a/src/lib-mail/message-part-data.h b/src/lib-mail/message-part-data.h index 9513bfc..1514f0d 100644 --- a/src/lib-mail/message-part-data.h +++ b/src/lib-mail/message-part-data.h @@ -8,6 +8,11 @@ struct message_header_line; +struct message_part_data_limits { +}; + +#define MESSAGE_PART_DATA_LIMITS_INIT { } + struct message_part_param { const char *name; const char *value; @@ -91,11 +96,13 @@ bool message_part_is_attachment(struct message_part *part, /* Update envelope data based from given header field */ void message_part_envelope_parse_from_header(pool_t pool, struct message_part_envelope **_data, + struct message_part_data_limits *limits, struct message_header_line *hdr); /* Parse a single header. Note that this modifies part->context. */ void message_part_data_parse_from_header(pool_t pool, struct message_part *part, + struct message_part_data_limits *limits, struct message_header_line *hdr); #endif diff --git a/src/lib-mail/test-message-decoder.c b/src/lib-mail/test-message-decoder.c index 83c2671..ad212c8 100644 --- a/src/lib-mail/test-message-decoder.c +++ b/src/lib-mail/test-message-decoder.c @@ -260,8 +260,10 @@ static void test_message_decoder_content_transfer_encoding(void) parser = message_parser_init(pool, istream, &parser_set); decoder = message_decoder_init(NULL, 0); + struct message_part_data_limits limits = MESSAGE_PART_DATA_LIMITS_INIT; while ((ret = message_parser_parse_next_block(parser, &input)) > 0) { - message_part_data_parse_from_header(pool, input.part, input.hdr); + message_part_data_parse_from_header(pool, input.part, &limits, + input.hdr); if (message_decoder_decode_next_block(decoder, &input, &output) && output.hdr == NULL && output.size > 0) str_append_data(str_out, output.data, output.size); @@ -349,8 +351,10 @@ static void test_message_decoder_invalid_content_transfer_encoding(void) parser = message_parser_init(pool, istream, &parser_set); decoder = message_decoder_init(NULL, 0); + struct message_part_data_limits limits = MESSAGE_PART_DATA_LIMITS_INIT; while ((ret = message_parser_parse_next_block(parser, &input)) > 0) { - message_part_data_parse_from_header(pool, input.part, input.hdr); + message_part_data_parse_from_header(pool, input.part, &limits, + input.hdr); if (input.hdr != NULL && strcasecmp(input.hdr->name, "content-transfer-encoding") == 0) { enum message_cte cte = message_decoder_parse_cte(input.hdr); @@ -480,8 +484,10 @@ UNICODE_REPLACEMENT_CHAR_UTF8; parser = message_parser_init(pool, istream, &parser_set); decoder = message_decoder_init(NULL, 0); + struct message_part_data_limits limits = MESSAGE_PART_DATA_LIMITS_INIT; while ((ret = message_parser_parse_next_block(parser, &input)) > 0) { - message_part_data_parse_from_header(pool, input.part, input.hdr); + message_part_data_parse_from_header(pool, input.part, &limits, + input.hdr); if (message_decoder_decode_next_block(decoder, &input, &output) && output.hdr == NULL && output.size > 0) str_append_data(str_out, output.data, output.size); @@ -531,8 +537,10 @@ static void test_message_decoder_charset_mime_part_change(void) parser = message_parser_init(pool, istream, &parser_set); decoder = message_decoder_init(NULL, 0); + struct message_part_data_limits limits = MESSAGE_PART_DATA_LIMITS_INIT; while ((ret = message_parser_parse_next_block(parser, &input)) > 0) { - message_part_data_parse_from_header(pool, input.part, input.hdr); + message_part_data_parse_from_header(pool, input.part, &limits, + input.hdr); if (message_decoder_decode_next_block(decoder, &input, &output) && output.hdr == NULL && output.size > 0) str_append_data(str_out, output.data, output.size); diff --git a/src/lib-mail/test-message-parser.c b/src/lib-mail/test-message-parser.c index 3b94034..b66e0a6 100644 --- a/src/lib-mail/test-message-parser.c +++ b/src/lib-mail/test-message-parser.c @@ -51,12 +51,13 @@ static int message_parse_stream(pool_t pool, struct istream *input, struct message_parser_ctx *parser; struct message_block block; + struct message_part_data_limits limits = MESSAGE_PART_DATA_LIMITS_INIT; i_zero(&block); parser = message_parser_init(pool, input, set); while ((ret = message_parser_parse_next_block(parser, &block)) > 0) if (parse_data) message_part_data_parse_from_header(pool, block.part, - block.hdr); + &limits, block.hdr); message_parser_deinit(&parser, parts_r); test_assert(input->stream_errno == 0); return ret; diff --git a/src/lib-mail/test-message-part-data.c b/src/lib-mail/test-message-part-data.c index 470d739..63228d1 100644 --- a/src/lib-mail/test-message-part-data.c +++ b/src/lib-mail/test-message-part-data.c @@ -14,12 +14,13 @@ static int message_parse_stream(pool_t pool, struct istream *input, struct message_parser_ctx *parser; struct message_block block; + struct message_part_data_limits limits = MESSAGE_PART_DATA_LIMITS_INIT; i_zero(&block); parser = message_parser_init(pool, input, set); while ((ret = message_parser_parse_next_block(parser, &block)) > 0) if (parse_data) message_part_data_parse_from_header(pool, block.part, - block.hdr); + &limits, block.hdr); message_parser_deinit(&parser, parts_r); test_assert(input->stream_errno == 0); return ret; diff --git a/src/lib-storage/index/index-mail-headers.c b/src/lib-storage/index/index-mail-headers.c index a9f4d55..9d608ac 100644 --- a/src/lib-storage/index/index-mail-headers.c +++ b/src/lib-storage/index/index-mail-headers.c @@ -308,12 +308,15 @@ void index_mail_parse_header(struct message_part *part, if (data->save_bodystructure_header && !data->parsed_bodystructure_header) { i_assert(part != NULL); - message_part_data_parse_from_header(mail->mail.data_pool, part, hdr); + message_part_data_parse_from_header(mail->mail.data_pool, part, + &mail->data.part_data_limits, + hdr); } if (data->save_envelope) { message_part_envelope_parse_from_header(mail->mail.data_pool, - &data->envelope_data, hdr); + &data->envelope_data, + &mail->data.part_data_limits, hdr); if (hdr == NULL) index_mail_parse_finish_imap_envelope(mail); @@ -510,7 +513,8 @@ imap_envelope_parse_callback(struct message_header_line *hdr, struct index_mail *mail) { message_part_envelope_parse_from_header(mail->mail.data_pool, - &mail->data.envelope_data, hdr); + &mail->data.envelope_data, + &mail->data.part_data_limits, hdr); if (hdr == NULL) index_mail_parse_finish_imap_envelope(mail); diff --git a/src/lib-storage/index/index-mail.c b/src/lib-storage/index/index-mail.c index 70060ba..3911f6d 100644 --- a/src/lib-storage/index/index-mail.c +++ b/src/lib-storage/index/index-mail.c @@ -696,11 +696,16 @@ void index_mail_cache_pop3_data(struct mail *_mail, &order, sizeof(order)); } +struct parse_bodystructure_ctx { + pool_t pool; + struct message_part_data_limits *limits; +}; + static void parse_bodystructure_part_header(struct message_part *part, struct message_header_line *hdr, - pool_t pool) + struct parse_bodystructure_ctx *ctx) { - message_part_data_parse_from_header(pool, part, hdr); + message_part_data_parse_from_header(ctx->pool, part, ctx->limits, hdr); } static bool want_plain_bodystructure_cached(struct index_mail *mail) @@ -1317,9 +1322,13 @@ static int index_mail_parse_body(struct index_mail *mail, /* bodystructure header is parsed, we want the body's mime headers too */ i_assert(data->parsed_bodystructure_header); + struct parse_bodystructure_ctx bsctx = { + .pool = mail->mail.data_pool, + .limits = &mail->data.part_data_limits, + }; message_parser_parse_body(data->parser_ctx, parse_bodystructure_part_header, - mail->mail.data_pool); + &bsctx); } else { message_parser_parse_body(data->parser_ctx, *null_message_part_header_callback, NULL); @@ -1860,6 +1869,8 @@ static void index_mail_init_data(struct index_mail *mail) data->received_date = (time_t)-1; data->sent_date.time = (uint32_t)-1; data->dont_cache_field_idx = UINT_MAX; + data->part_data_limits = (struct message_part_data_limits) + MESSAGE_PART_DATA_LIMITS_INIT; data->wanted_fields = mail->mail.wanted_fields; if (mail->mail.wanted_headers != NULL) { @@ -2321,7 +2332,9 @@ void index_mail_cache_parse_continue(struct mail *_mail) mail->data.header_parsed = TRUE; } else { message_part_data_parse_from_header(mail->mail.data_pool, - block.part, block.hdr); + block.part, + &mail->data.part_data_limits, + block.hdr); } } } diff --git a/src/lib-storage/index/index-mail.h b/src/lib-storage/index/index-mail.h index 9e21598..d1625b3 100644 --- a/src/lib-storage/index/index-mail.h +++ b/src/lib-storage/index/index-mail.h @@ -2,6 +2,7 @@ #define INDEX_MAIL_H #include "message-size.h" +#include "message-part-data.h" #include "mail-cache.h" #include "mail-storage-private.h" @@ -84,6 +85,7 @@ struct index_mail_data { const char *envelope, *body, *bodystructure, *guid, *filename; const char *from_envelope, *body_snippet; struct message_part_envelope *envelope_data; + struct message_part_data_limits part_data_limits; uint32_t cache_flags; uint64_t modseq, pvt_modseq;