patch reduced to code only

From: Jeremy Harris <jgh146exb@wizmail.org>
Date: Mon, 1 Jul 2024 18:35:12 +0000 (+0100)
Subject: Fix MIME parsing of filenames specified using multiple parameters.  Bug 3099
X-Git-Tag: exim-4.98-RC3~2
X-Git-Url: https://git.exim.org/exim.git/commitdiff_plain/6ce5c70cff89

Fix MIME parsing of filenames specified using multiple parameters.  Bug 3099
---

diff --git a/src/src/mime.c b/src/src/mime.c
index 975ddca85..5f9e1ade7 100644
--- a/src/src/mime.c
+++ b/src/src/mime.c
@@ -587,10 +587,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 */
@@ -604,11 +604,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);
@@ -623,26 +624,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
@@ -651,9 +658,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 */
@@ -682,7 +689,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 */
