160 lines
5.4 KiB
Diff
160 lines
5.4 KiB
Diff
From 6ce5c70cff8989418e05d01fd2a57703007a6357 Mon Sep 17 00:00:00 2001
|
|
From: Jeremy Harris <jgh146exb@wizmail.org>
|
|
Date: Mon, 1 Jul 2024 19:35:12 +0100
|
|
Subject: [PATCH] Fix MIME parsing of filenames specified using multiple
|
|
parameters. Bug 3099
|
|
|
|
---
|
|
doc/ChangeLog | 3 +++
|
|
doc/spec.txt | 10 +++++-----
|
|
src/mime.c | 51 +++++++++++++++++++++++++++++----------------------
|
|
3 files changed, 37 insertions(+), 27 deletions(-)
|
|
|
|
diff --git a/doc/ChangeLog b/doc/ChangeLog
|
|
index 3e6da91..095bdb4 100644
|
|
--- a/doc/ChangeLog
|
|
+++ b/doc/ChangeLog
|
|
@@ -148,6 +148,9 @@ JH/32 Fix CHUNKING for a second message on a connection when the first was
|
|
JH/33 Fis ${srs_encode ...} to handle an empty sender address, now returning
|
|
an empty address. Previously the expansion returned an error.
|
|
|
|
+JH/34 Bug 3099: fix parsing of MIME filenames split over multiple paramemters.
|
|
+ Previously the $mime_filename variable would have an incorrect value.
|
|
+
|
|
HS/01 Bug 2855: Handle a v4mapped sender address given us by a frontending
|
|
proxy. Previously these were misparsed, leading to paniclog entries.
|
|
|
|
diff --git a/doc/spec.txt b/doc/spec.txt
|
|
index ddadcaf..9128166 100644
|
|
--- a/doc/spec.txt
|
|
+++ b/doc/spec.txt
|
|
@@ -32165,13 +32165,13 @@ The right hand side is expanded before use. After expansion, the value can be:
|
|
the default path is then used.
|
|
|
|
The decode condition normally succeeds. It is only false for syntax errors or
|
|
-unusual circumstances such as memory shortages. You can easily decode a file
|
|
-with its original, proposed filename using
|
|
+errors or unusual circumstances such as memory shortages.
|
|
|
|
-decode = $mime_filename
|
|
+The variable &$mime_filename$& will have the suggested name for the file.
|
|
+Note however that this might contain anything, and is very difficult
|
|
+to safely use as all or even part of the filename.
|
|
|
|
-However, you should keep in mind that $mime_filename might contain anything. If
|
|
-you place files outside of the default path, they are not automatically
|
|
+If you place files outside of the default path, they are not
|
|
unlinked.
|
|
|
|
For RFC822 attachments (these are messages attached to messages, with a
|
|
diff --git a/src/mime.c b/src/mime.c
|
|
index c192199..e7af413 100644
|
|
--- a/src/mime.c
|
|
+++ b/src/mime.c
|
|
@@ -586,10 +586,10 @@ while(1)
|
|
|
|
while (*p)
|
|
{
|
|
- DEBUG(D_acl) debug_printf_indent("MIME: considering paramlist '%s'\n", p);
|
|
+ DEBUG(D_acl)
|
|
+ debug_printf_indent("MIME: considering paramlist '%s'\n", p);
|
|
|
|
- if ( !mime_filename
|
|
- && strncmpic(CUS"content-disposition:", header, 20) == 0
|
|
+ if ( strncmpic(CUS"content-disposition:", header, 20) == 0
|
|
&& strncmpic(CUS"filename*", p, 9) == 0
|
|
)
|
|
{ /* RFC 2231 filename */
|
|
@@ -603,11 +603,12 @@ while(1)
|
|
|
|
if (q && *q)
|
|
{
|
|
- uschar * temp_string, * err_msg;
|
|
+ uschar * temp_string, * err_msg, * fname = q;
|
|
int slen;
|
|
|
|
/* build up an un-decoded filename over successive
|
|
filename*= parameters (for use when 2047 decode fails) */
|
|
+/*XXX could grow a gstring here */
|
|
|
|
mime_fname_rfc2231 = string_sprintf("%#s%s",
|
|
mime_fname_rfc2231, q);
|
|
@@ -622,26 +623,32 @@ while(1)
|
|
/* look for a ' in the "filename" */
|
|
while(*s != '\'' && *s) s++; /* s is 1st ' or NUL */
|
|
|
|
- if ((size = s-q) > 0)
|
|
- mime_filename_charset = string_copyn(q, size);
|
|
+ if (*s) /* there was a ' */
|
|
+ {
|
|
+ if ((size = s-q) > 0)
|
|
+ mime_filename_charset = string_copyn(q, size);
|
|
|
|
- if (*(p = s)) p++;
|
|
- while(*p == '\'') p++; /* p is after 2nd ' */
|
|
+ if (*(fname = s)) fname++;
|
|
+ while(*fname == '\'') fname++; /* fname is after 2nd ' */
|
|
+ }
|
|
}
|
|
- else
|
|
- p = q;
|
|
|
|
- DEBUG(D_acl) debug_printf_indent("MIME: charset %s fname '%s'\n",
|
|
- mime_filename_charset ? mime_filename_charset : US"<NULL>", p);
|
|
+ DEBUG(D_acl)
|
|
+ debug_printf_indent("MIME: charset %s fname '%s'\n",
|
|
+ mime_filename_charset ? mime_filename_charset : US"<NULL>",
|
|
+ fname);
|
|
|
|
- temp_string = rfc2231_to_2047(p, mime_filename_charset, &slen);
|
|
- DEBUG(D_acl) debug_printf_indent("MIME: 2047-name %s\n", temp_string);
|
|
+ temp_string = rfc2231_to_2047(fname, mime_filename_charset,
|
|
+ &slen);
|
|
+ DEBUG(D_acl)
|
|
+ debug_printf_indent("MIME: 2047-name %s\n", temp_string);
|
|
|
|
temp_string = rfc2047_decode(temp_string, FALSE, NULL, ' ',
|
|
- NULL, &err_msg);
|
|
- DEBUG(D_acl) debug_printf_indent("MIME: plain-name %s\n", temp_string);
|
|
+ NULL, &err_msg);
|
|
+ DEBUG(D_acl)
|
|
+ debug_printf_indent("MIME: plain-name %s\n", temp_string);
|
|
|
|
- if (!temp_string || (size = Ustrlen(temp_string)) == slen)
|
|
+ if (!temp_string || (size = Ustrlen(temp_string)) == slen)
|
|
decoding_failed = TRUE;
|
|
else
|
|
/* build up a decoded filename over successive
|
|
@@ -650,9 +657,9 @@ while(1)
|
|
mime_filename = mime_fname = mime_fname
|
|
? string_sprintf("%s%s", mime_fname, temp_string)
|
|
: temp_string;
|
|
- }
|
|
- }
|
|
- }
|
|
+ } /*!decoding_failed*/
|
|
+ } /*q*/
|
|
+ } /*2231 filename*/
|
|
|
|
else
|
|
/* look for interesting parameters */
|
|
@@ -681,7 +688,7 @@ while(1)
|
|
|
|
|
|
/* There is something, but not one of our interesting parameters.
|
|
- Advance past the next semicolon */
|
|
+ Advance past the next semicolon */
|
|
p = mime_next_semicolon(p);
|
|
if (*p) p++;
|
|
} /* param scan on line */
|
|
@@ -799,5 +806,5 @@ return rc;
|
|
|
|
#endif /*WITH_CONTENT_SCAN*/
|
|
|
|
-/* vi: sw ai sw=2
|
|
+/* vi: aw ai sw=2
|
|
*/
|
|
--
|
|
2.33.0
|
|
|