summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2023-03-16 15:49:59 +0000
committerJeremy Harris <jgh146exb@wizmail.org>2023-03-16 17:04:28 +0000
commit3607e3e00236f6039b765882edd0200dff6a31fc (patch)
treed90143e887fa2a2bdbd5ed96287e97871d765184 /src
parent3af9f77fb401fe0e77a46a88415c6e45ed1a47bf (diff)
Limit expanded References header to RFC max size. Bug 2827
Diffstat (limited to 'src')
-rw-r--r--src/src/deliver.c1
-rw-r--r--src/src/moan.c35
2 files changed, 28 insertions, 8 deletions
diff --git a/src/src/deliver.c b/src/src/deliver.c
index e2994b116..57a435eeb 100644
--- a/src/src/deliver.c
+++ b/src/src/deliver.c
@@ -6178,6 +6178,7 @@ return_path = sender_address; /* In case not previously set */
/* Write the original email out */
/*XXX no checking for failure! buggy! */
+/*XXX overlong headers in the original become overlong body lines here*/
transport_write_message(&tctx, 0);
fflush(f);
diff --git a/src/src/moan.c b/src/src/moan.c
index ebfd440f6..9c30c8edd 100644
--- a/src/src/moan.c
+++ b/src/src/moan.c
@@ -80,11 +80,17 @@ if (!h)
/* We limit the total length of references. Although there is no fixed
limit, some systems do not like headers growing beyond recognition.
Keep the first message ID for the thread root and the last few for
-the position inside the thread, up to a maximum of 12 altogether. */
+the position inside the thread, up to a maximum of 12 altogether.
+Also apply the max line length limit from RFC 2822 2.1.1
+
+XXX preferably we would get any limit from the outbound transport,
+passed in here for a limit value.
+*/
if (h || message_id)
{
- fprintf(fp, "References:");
+ unsigned use = fprintf(fp, "References:");
+ if (message_id) use += Ustrlen(message_id) + 1;
if (h)
{
const uschar * s;
@@ -95,14 +101,27 @@ if (h || message_id)
s = Ustrchr(h->text, ':') + 1;
f.parse_allow_group = FALSE;
while (*s && (s = parse_message_id(s, &id, &error)))
- if (reference_count == nelem(referenced_ids))
- {
- memmove(referenced_ids + 1, referenced_ids + 2,
- sizeof(referenced_ids) - 2*sizeof(uschar *));
- referenced_ids[reference_count - 1] = id;
- }
+ {
+ unsigned this = Ustrlen(id);
+ if ( reference_count == nelem(referenced_ids)
+ || use + this + reference_count > 998
+ )
+ {
+ if (reference_count > 1)
+ {
+ /* drop position 1 and shuffle down */
+ use -= Ustrlen(referenced_ids + 1);
+ memmove(referenced_ids + 1, referenced_ids + 2,
+ sizeof(referenced_ids) - 2*sizeof(*referenced_ids));
+
+ /* append new one */
+ referenced_ids[reference_count - 1] = id;
+ }
+ }
else
referenced_ids[reference_count++] = id;
+ use += this;
+ }
for (int i = 0; i < reference_count; ++i)
fprintf(fp, " %s", referenced_ids[i]);