filename, and the default path is then used.
.endlist
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
-.code
-decode = $mime_filename
-.endd
-However, you should keep in mind that &$mime_filename$& might contain
-anything. If you place files outside of the default path, they are not
+errors or unusual circumstances such as memory shortages.
+.new
+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.
+.wen
+If you place files outside of the default path, they are not
automatically unlinked.
For RFC822 attachments (these are messages attached to messages, with a
JH/34 Fix delivery ordering for 2-phase queue run combined with
queue_run_in_order.
+JH/35 Bug 3099: fix parsing of MIME filenames split over multiple paramemters.
+ Previously the $mime_filename variable would have an incorrect value.
+
Exim version 4.97
-----------------
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 */
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);
/* 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
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 */
/* 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 */
#endif /*WITH_CONTENT_SCAN*/
-/* vi: sw ai sw=2
+/* vi: aw ai sw=2
*/
Precision: dot, followed by decimal digits or *
Length modifiers: h L l ll z
Conversion specifiers: n d o u x X p f e E g G % c s S T W V Y D M
+Alternate-form: %#s is silent about a null string
Returns the possibly-new (if copy for growth or taint-handling was needed)
string, not nul-terminated.
1999-03-02 09:44:33 10HmbE-000000005vi-0000 => userx <userx@test.ex> R=r1 T=t1
1999-03-02 09:44:33 10HmbE-000000005vi-0000 Completed
1999-03-02 09:44:33 10HmaX-000000005vi-0000 U=CALLER F=<CALLER@myhost.test.ex> rejected during MIME ACL checks: this is a deny from the mime acl
+1999-03-02 09:44:33 10HmbF-000000005vi-0000 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss T="Bug 3099 (2)"
+1999-03-02 09:44:33 10HmbF-000000005vi-0000 => userx <userx@test.ex> R=r1 T=t1
+1999-03-02 09:44:33 10HmbF-000000005vi-0000 Completed
--T4sUOijqQbZv57TR--
+From CALLER@myhost.test.ex Tue Mar 02 09:44:33 1999
+Received: from CALLER (helo=test.ex)
+ by myhost.test.ex with local-esmtp (Exim x.yz)
+ (envelope-from <CALLER@myhost.test.ex>)
+ id 10HmbF-000000005vi-0000
+ for userx@test.ex;
+ Tue, 2 Mar 1999 09:44:33 +0000
+From: localpart@test.example
+To: localpart@test.example
+Subject: Bug 3099 (2)
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="----=_MIME_BOUNDARY_000_695039"
+Message-Id: <E10HmbF-000000005vi-0000@myhost.test.ex>
+Sender: CALLER_NAME <CALLER@myhost.test.ex>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+X-0-content-type: multipart/mixed
+X-0-filename:
+X-0-charset:
+X-0-boundary: ----=_MIME_BOUNDARY_000_695039
+X-0-content-disposition:
+X-0-content-transfer-encoding:
+X-0-content-id:
+X-0-content-description:
+X-0-is-multipart: 1
+X-0-is-coverletter: 1
+X-0-is-rfc822: 0
+X-0-decode-filename: TESTSUITE/spool/scan/10HmbF-000000005vi-0000/10HmbF-000000005vi-0000-00000
+X-0-content-size: 1
+X-1-content-type: text/plain
+X-1-filename:
+X-1-charset:
+X-1-boundary:
+X-1-content-disposition:
+X-1-content-transfer-encoding:
+X-1-content-id:
+X-1-content-description:
+X-1-is-multipart: 0
+X-1-is-coverletter: 1
+X-1-is-rfc822: 0
+X-1-decode-filename: TESTSUITE/spool/scan/10HmbF-000000005vi-0000/10HmbF-000000005vi-0000-00001
+X-1-content-size: 1
+X-2-content-type: application/octet-stream
+X-2-filename: example3.exe
+X-2-charset:
+X-2-boundary:
+X-2-content-disposition: attachment
+X-2-content-transfer-encoding: base64
+X-2-content-id:
+X-2-content-description:
+X-2-is-multipart: 0
+X-2-is-coverletter: 0
+X-2-is-rfc822: 0
+X-2-decode-filename: TESTSUITE/spool/scan/10HmbF-000000005vi-0000/10HmbF-000000005vi-0000-00002
+X-2-content-size: 1
+
+------=_MIME_BOUNDARY_000_695039
+Content-Type: text/plain
+
+This is a test mailing
+------=_MIME_BOUNDARY_000_695039
+Content-Type: application/octet-stream
+Content-Disposition: attachment;
+ filename*0*="example3";
+ filename*1*=".exe"
+Content-Transfer-Encoding: BASE64
+
+QmVpc3BpZWwK
+
+------=_MIME_BOUNDARY_000_695039--
+
.
quit
****
+#
+#
+# Filename using parameter value continuation (RFC 2231 sec. 3)
+exim -odi -bs
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+From: localpart@test.example
+To: localpart@test.example
+Subject: Bug 3099 (2)
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="----=_MIME_BOUNDARY_000_695039"
+
+------=_MIME_BOUNDARY_000_695039
+Content-Type: text/plain
+
+This is a test mailing
+------=_MIME_BOUNDARY_000_695039
+Content-Type: application/octet-stream
+Content-Disposition: attachment;
+ filename*0*="example3";
+ filename*1*=".exe"
+Content-Transfer-Encoding: BASE64
+
+QmVpc3BpZWwK
+
+------=_MIME_BOUNDARY_000_695039--
+.
+quit
+****
354 Enter message, ending with "." on a line by itself\r
550 this is a deny from the mime acl\r
221 myhost.test.ex closing connection\r
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-myhost.test.ex Hello CALLER at test.ex\r
+250-SIZE 52428800\r
+250-LIMITS MAILMAX=1000 RCPTMAX=50000\r
+250-8BITMIME\r
+250-PIPELINING\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbF-000000005vi-0000\r
+221 myhost.test.ex closing connection\r