MIME: fix crash on filenames having null charset. Bug 1730
authorJeremy Harris <jgh146exb@wizmail.org>
Wed, 25 Nov 2015 17:49:03 +0000 (17:49 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Wed, 25 Nov 2015 17:49:03 +0000 (17:49 +0000)
src/src/mime.c
test/log/4000
test/mail/4000.userx
test/scripts/4000-scanning/4000
test/stdout/4000

index 618364a3ecbbde1bcc0de6e4e63518c08fdf86b1..cc9ffb7c6f3928aa841ae84a434dbe0af9782a44 100644 (file)
@@ -550,7 +550,8 @@ int size = 0, ptr = 0;
 uschar * val = string_cat(NULL, &size, &ptr, US"=?", 2);
 uschar c;
 
 uschar * val = string_cat(NULL, &size, &ptr, US"=?", 2);
 uschar c;
 
-val = string_cat(val, &size, &ptr, charset, Ustrlen(charset));
+if (charset)
+  val = string_cat(val, &size, &ptr, charset, Ustrlen(charset));
 val = string_cat(val, &size, &ptr, US"?Q?", 3);
 
 while ((c = *fname))
 val = string_cat(val, &size, &ptr, US"?Q?", 3);
 
 while ((c = *fname))
@@ -607,7 +608,7 @@ while(1)
     if (!fgets(CS header, MIME_MAX_HEADER_SIZE, f))
       {
       /* Hit EOF or read error. Ugh. */
     if (!fgets(CS header, MIME_MAX_HEADER_SIZE, f))
       {
       /* Hit EOF or read error. Ugh. */
-      DEBUG(D_acl) debug_printf("Hit EOF ...\n");
+      DEBUG(D_acl) debug_printf("MIME: Hit EOF ...\n");
       return rc;
       }
 
       return rc;
       }
 
@@ -619,12 +620,12 @@ while(1)
       if (Ustrncmp((header+2+Ustrlen(context->boundary)), "--", 2) == 0)
        {
        /* END boundary found */
       if (Ustrncmp((header+2+Ustrlen(context->boundary)), "--", 2) == 0)
        {
        /* END boundary found */
-       DEBUG(D_acl) debug_printf("End boundary found %s\n",
+       DEBUG(D_acl) debug_printf("MIME: End boundary found %s\n",
          context->boundary);
        return rc;
        }
 
          context->boundary);
        return rc;
        }
 
-      DEBUG(D_acl) debug_printf("Next part with boundary %s\n",
+      DEBUG(D_acl) debug_printf("MIME: Next part with boundary %s\n",
        context->boundary);
       break;
       }
        context->boundary);
       break;
       }
@@ -648,7 +649,7 @@ while(1)
 
       for (q = p; *q != ';' && *q; q++) ;
       *mh->value = string_copynlc(p, q-p);
 
       for (q = p; *q != ';' && *q; q++) ;
       *mh->value = string_copynlc(p, q-p);
-      DEBUG(D_acl) debug_printf("found %s MIME header, value is '%s'\n",
+      DEBUG(D_acl) debug_printf("MIME: found %s header, value is '%s'\n",
        mh->name, *mh->value);
 
       if (*(p = q)) p++;                       /* jump past the ; */
        mh->name, *mh->value);
 
       if (*(p = q)) p++;                       /* jump past the ; */
@@ -666,7 +667,7 @@ while(1)
          {
          mime_parameter * mp;
 
          {
          mime_parameter * mp;
 
-         DEBUG(D_acl) debug_printf("  considering paramlist '%s'\n", p);
+         DEBUG(D_acl) debug_printf("MIME:   considering paramlist '%s'\n", p);
 
          if (  !mime_filename
             && strncmpic(CUS"content-disposition:", header, 20) == 0
 
          if (  !mime_filename
             && strncmpic(CUS"content-disposition:", header, 20) == 0
@@ -700,22 +701,27 @@ while(1)
                  uschar * s = q;
 
                  /* look for a ' in the "filename" */
                  uschar * s = q;
 
                  /* look for a ' in the "filename" */
-                 while(*s != '\'' && *s) s++;  /* s is ' or NUL */
+                 while(*s != '\'' && *s) s++;  /* s is 1st ' or NUL */
 
                  if ((size = s-q) > 0)
 
                  if ((size = s-q) > 0)
-                   {
                    mime_filename_charset = string_copyn(q, size);
                    mime_filename_charset = string_copyn(q, size);
-                   p = s;
 
 
-                   while(*p == '\'' && *p) p++; /* p is after ' */
-                   }
+                 if (*(p = s)) p++;
+                 while(*p == '\'') p++;        /* p is after 2nd ' */
                  }
                else
                  p = q;
 
                  }
                else
                  p = q;
 
+               DEBUG(D_acl) debug_printf("MIME:    charset %s fname '%s'\n",
+                 mime_filename_charset ? mime_filename_charset : US"<NULL>", p);
+
                temp_string = rfc2231_to_2047(p, mime_filename_charset, &slen);
                temp_string = rfc2231_to_2047(p, mime_filename_charset, &slen);
-               temp_string = rfc2047_decode(temp_string, FALSE, NULL, 32,
+               DEBUG(D_acl) debug_printf("MIME:    2047-name %s\n", temp_string);
+
+               temp_string = rfc2047_decode(temp_string, FALSE, NULL, ' ',
                  NULL, &err_msg);
                  NULL, &err_msg);
+               DEBUG(D_acl) debug_printf("MIME:    plain-name %s\n", temp_string);
+
                size = Ustrlen(temp_string);
 
                if (size == slen)
                size = Ustrlen(temp_string);
 
                if (size == slen)
@@ -750,7 +756,7 @@ while(1)
                    &dummy_errstr)
                : NULL;
              DEBUG(D_acl) debug_printf(
                    &dummy_errstr)
                : NULL;
              DEBUG(D_acl) debug_printf(
-               " found %s MIME parameter in %s header, value '%s'\n",
+               "MIME:  found %s parameter in %s header, value '%s'\n",
                mp->name, mh->name, *mp->value);
 
              break;                    /* done matching param names */
                mp->name, mh->name, *mp->value);
 
              break;                    /* done matching param names */
@@ -768,7 +774,7 @@ while(1)
          if (decoding_failed) mime_filename = mime_fname_rfc2231;
 
          DEBUG(D_acl) debug_printf(
          if (decoding_failed) mime_filename = mime_fname_rfc2231;
 
          DEBUG(D_acl) debug_printf(
-           " found %s MIME parameter in %s header, value is '%s'\n",
+           "MIME:  found %s parameter in %s header, value is '%s'\n",
            "filename", mh->name, mime_filename);
          }
        }
            "filename", mh->name, mime_filename);
          }
        }
@@ -809,8 +815,9 @@ while(1)
        (nested_context.boundary != NULL) &&
        (Ustrncmp(mime_content_type,"multipart",9) == 0) )
     {
        (nested_context.boundary != NULL) &&
        (Ustrncmp(mime_content_type,"multipart",9) == 0) )
     {
-    DEBUG(D_acl) debug_printf("Entering multipart recursion, boundary '%s'\n",
-      nested_context.boundary);
+    DEBUG(D_acl)
+      debug_printf("MIME: Entering multipart recursion, boundary '%s'\n",
+       nested_context.boundary);
 
     nested_context.context =
       context && context->context == MBC_ATTACHMENT
 
     nested_context.context =
       context && context->context == MBC_ATTACHMENT
index bb1a04fe9a32339a031c1f6e742ebc8192b74ce0..c39fb583cf122b6f9d867031e04eb94be171bee6 100644 (file)
@@ -13,6 +13,9 @@
 1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=20041217133501.GA3059@test.ex T="Nasty4"
 1999-03-02 09:44:33 10HmbB-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
 1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
 1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=20041217133501.GA3059@test.ex T="Nasty4"
 1999-03-02 09:44:33 10HmbB-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
 1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=20041217133501.GA3058@test.ex
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=20041217133501.GA3058@test.ex T="Nasty5"
 1999-03-02 09:44:33 10HmbC-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
 1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
 1999-03-02 09:44:33 10HmbC-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
 1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=20041217133502.GA3059@test.ex T="Nasty6"
+1999-03-02 09:44:33 10HmbD-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
+1999-03-02 09:44:33 10HmbD-0005vi-00 Completed
index f59b904f3291d00b1952af60ed2a0f30f41f1a61..486fb039d391e9e52294aff78f18d95d77538ce7 100644 (file)
@@ -303,6 +303,7 @@ Received: from CALLER (helo=test.ex)
        for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
 Date: Tue, 2 Mar 1999 09:44:33 +0000
 Message-ID: <20041217133501.GA3058@test.ex>
        for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
 Date: Tue, 2 Mar 1999 09:44:33 +0000
 Message-ID: <20041217133501.GA3058@test.ex>
+Subject: Nasty5
 Mime-Version: 1.0
 Content-Type: multipart/mixed; boundary="T4sUOijqQbZv57TR"
 From: CALLER_NAME <CALLER@myhost.test.ex>
 Mime-Version: 1.0
 Content-Type: multipart/mixed; boundary="T4sUOijqQbZv57TR"
 From: CALLER_NAME <CALLER@myhost.test.ex>
@@ -360,3 +361,41 @@ Content-Disposition: attachment; filename*=ISO-8859-1''%74%65%73%74%20%E4%20%74%
 
 --T4sUOijqQbZv57TR--
 
 
 --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 10HmbD-0005vi-00
+       for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+From: J Caesar <jcaesar@test.ex>
+To: a-list00@exim.org
+Message-ID: <20041217133502.GA3059@test.ex>
+Mime-Version: 1.0
+Content-Type: application/pdf;
+ name*=''2015.11.13%20-%20Pr%C3%A4sentation%20GI%20-%20LK.PDF
+Content-Disposition: attachment;
+ filename*=''2015.11.13%20-%20Pr%C3%A4sentation%20GI%20-%20LK.PDF
+Subject: Nasty6
+Sender: CALLER_NAME <CALLER@myhost.test.ex>
+X-0-content-type: application/pdf
+X-0-filename: 2015.11.13 - Präsentation GI - LK.PDF
+X-0-charset: 
+X-0-boundary: 
+X-0-content-disposition: attachment
+X-0-content-transfer-encoding: 
+X-0-content-id: 
+X-0-content-description: 
+X-0-is-multipart: 0
+X-0-is-coverletter: 1
+X-0-is-rfc822: 0
+X-0-decode-filename: TESTSUITE/spool/scan/10HmbD-0005vi-00/10HmbD-0005vi-00-00000
+X-0-content-size: 1
+
+--T4sUOijqQbZv57TR
+Content-Type: text/plain;
+
+foobar
+
+--T4sUOijqQbZv57TR--
+
index eda235b10bfb8c6f5819b77d1430837d3de5f6a8..b29aed1e01f5d5bb7bf5fc0b7e7bce6d4e920ccd 100644 (file)
@@ -194,6 +194,7 @@ rcpt to:<userx@test.ex>
 data
 Date: Fri, 17 Dec 2004 14:35:01 +0100
 Message-ID: <20041217133501.GA3058@test.ex>
 data
 Date: Fri, 17 Dec 2004 14:35:01 +0100
 Message-ID: <20041217133501.GA3058@test.ex>
+Subject: Nasty5
 Mime-Version: 1.0
 Content-Type: multipart/mixed; boundary="T4sUOijqQbZv57TR"
 
 Mime-Version: 1.0
 Content-Type: multipart/mixed; boundary="T4sUOijqQbZv57TR"
 
@@ -213,3 +214,32 @@ Content-Disposition: attachment; filename*=ISO-8859-1''%74%65%73%74%20%E4%20%74%
 .
 quit
 ****
 .
 quit
 ****
+#
+#
+# This one has a legit param; empty charset
+#
+exim -odi -bs
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+Date: Fri, 17 Dec 2004 14:35:01 +0100
+From: J Caesar <jcaesar@test.ex>
+To: a-list00@exim.org
+Message-ID: <20041217133502.GA3059@test.ex>
+Mime-Version: 1.0
+Content-Type: application/pdf;
+ name*=''2015.11.13%20-%20Pr%C3%A4sentation%20GI%20-%20LK.PDF
+Content-Disposition: attachment;
+ filename*=''2015.11.13%20-%20Pr%C3%A4sentation%20GI%20-%20LK.PDF
+Subject: Nasty6
+
+--T4sUOijqQbZv57TR
+Content-Type: text/plain;
+
+foobar
+
+--T4sUOijqQbZv57TR--
+.
+quit
+****
index 95511480eebcdc122bcd7a065f7c0f023cf0af97..c1e2b24508c364a31a8a641468255ac7585bd711 100644 (file)
 354 Enter message, ending with "." on a line by itself\r
 250 OK id=10HmbC-0005vi-00\r
 221 myhost.test.ex closing connection\r
 354 Enter message, ending with "." on a line by itself\r
 250 OK id=10HmbC-0005vi-00\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-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=10HmbD-0005vi-00\r
+221 myhost.test.ex closing connection\r