From: Vsevolod Stakhov Date: Thu, 23 Jul 2026 10:10:56 +0000 (+0100) Subject: [Fix] message: make newline metadata budget task-global, fix flag collision X-Git-Tag: 4.1.3~40 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=93e981e9d2cf62117c9539b58af995136d9bf54d;p=thirdparty%2Frspamd.git [Fix] message: make newline metadata budget task-global, fix flag collision --- diff --git a/src/libmime/message.c b/src/libmime/message.c index 7722ffc22f..9589096fa8 100644 --- a/src/libmime/message.c +++ b/src/libmime/message.c @@ -231,17 +231,26 @@ rspamd_mime_part_detect_language(struct rspamd_task *task, } } -/* Bound per-part newline metadata; the text itself is still normalized fully */ -static const unsigned int max_part_newlines = 100000; +/* Bound newline metadata for the whole message; the text itself is still normalized fully */ +static const unsigned int max_message_newlines = 100000; static inline void -rspamd_text_part_maybe_add_newline(struct rspamd_mime_text_part *part) +rspamd_text_part_maybe_add_newline(struct rspamd_task *task, + struct rspamd_mime_text_part *part) { - if (G_LIKELY(part->newlines->len < max_part_newlines)) { + if (G_LIKELY(MESSAGE_FIELD(task, ntext_newlines) < max_message_newlines)) { g_ptr_array_add(part->newlines, (((gpointer) (goffset) (part->utf_stripped_content->len)))); + MESSAGE_FIELD(task, ntext_newlines) += 1; } else { + if (!MESSAGE_FIELD(task, text_newlines_limit_reached)) { + msg_warn_task("too many newlines in message; only %ud newline " + "positions are recorded across all text parts", + max_message_newlines); + MESSAGE_FIELD(task, text_newlines_limit_reached) = TRUE; + } + part->flags |= RSPAMD_MIME_TEXT_PART_FLAG_NEWLINES_TRUNCATED; } } @@ -325,7 +334,7 @@ rspamd_strip_newlines_parse(struct rspamd_task *task, g_byte_array_append(part->utf_stripped_content, (const uint8_t *) " ", 1); crlf_added = TRUE; - rspamd_text_part_maybe_add_newline(part); + rspamd_text_part_maybe_add_newline(task, part); } part->nlines++; @@ -358,7 +367,7 @@ rspamd_strip_newlines_parse(struct rspamd_task *task, if (IS_TEXT_PART_HTML(part) || !url_open_bracket) { g_byte_array_append(part->utf_stripped_content, (const uint8_t *) " ", 1); - rspamd_text_part_maybe_add_newline(part); + rspamd_text_part_maybe_add_newline(task, part); crlf_added = TRUE; } else { @@ -375,7 +384,7 @@ rspamd_strip_newlines_parse(struct rspamd_task *task, crlf_added = TRUE; } - rspamd_text_part_maybe_add_newline(part); + rspamd_text_part_maybe_add_newline(task, part); } c = p + 1; @@ -388,7 +397,7 @@ rspamd_strip_newlines_parse(struct rspamd_task *task, g_byte_array_append(part->utf_stripped_content, (const uint8_t *) " ", 1); crlf_added = TRUE; - rspamd_text_part_maybe_add_newline(part); + rspamd_text_part_maybe_add_newline(task, part); } part->nlines++; @@ -441,7 +450,7 @@ rspamd_strip_newlines_parse(struct rspamd_task *task, part->nlines++; if (!crlf_added) { - rspamd_text_part_maybe_add_newline(part); + rspamd_text_part_maybe_add_newline(task, part); } /* Skip initial spaces */ @@ -508,7 +517,7 @@ rspamd_strip_newlines_parse(struct rspamd_task *task, if (!crlf_added) { g_byte_array_append(part->utf_stripped_content, (const uint8_t *) " ", 1); - rspamd_text_part_maybe_add_newline(part); + rspamd_text_part_maybe_add_newline(task, part); } part->nlines++; @@ -546,12 +555,6 @@ rspamd_normalize_text_part(struct rspamd_task *task, rspamd_strip_newlines_parse(task, p, end, part); - if (part->flags & RSPAMD_MIME_TEXT_PART_FLAG_NEWLINES_TRUNCATED) { - msg_warn_task("too many newlines in text part; only %ud newline " - "positions are recorded", - max_part_newlines); - } - for (i = 0; i < part->newlines->len; i++) { ex = rspamd_mempool_alloc(task->task_pool, sizeof(*ex)); off = (goffset) g_ptr_array_index(part->newlines, i); diff --git a/src/libmime/message.h b/src/libmime/message.h index 34cf99c97d..dff270f969 100644 --- a/src/libmime/message.h +++ b/src/libmime/message.h @@ -121,8 +121,8 @@ struct rspamd_mime_part { #define RSPAMD_MIME_TEXT_PART_FLAG_HTML (1 << 2) #define RSPAMD_MIME_TEXT_PART_FLAG_8BIT_RAW (1 << 3) #define RSPAMD_MIME_TEXT_PART_FLAG_8BIT_ENCODED (1 << 4) -#define RSPAMD_MIME_TEXT_PART_FLAG_NEWLINES_TRUNCATED (1 << 5) #define RSPAMD_MIME_TEXT_PART_ATTACHMENT (1 << 5) +#define RSPAMD_MIME_TEXT_PART_FLAG_NEWLINES_TRUNCATED (1 << 6) #define IS_TEXT_PART_EMPTY(part) ((part)->flags & RSPAMD_MIME_TEXT_PART_FLAG_EMPTY) #define IS_TEXT_PART_UTF(part) ((part)->flags & RSPAMD_MIME_TEXT_PART_FLAG_UTF)