diff -urN ../exim-4.89.orig/src/mime.c ./src/mime.c
--- ../exim-4.89.orig/src/mime.c	2017-03-04 23:21:35.000000000 +0200
+++ ./src/mime.c	2017-03-10 17:14:35.000000000 +0200
@@ -480,33 +480,6 @@
 }
 
 
-static uschar *
-rfc2231_to_2047(const uschar * fname, const uschar * charset, int * len)
-{
-int size = 0, ptr = 0;
-uschar * val = string_catn(NULL, &size, &ptr, US"=?", 2);
-uschar c;
-
-if (charset)
-  val = string_cat(val, &size, &ptr, charset);
-val = string_catn(val, &size, &ptr, US"?Q?", 3);
-
-while ((c = *fname))
-  if (c == '%' && isxdigit(fname[1]) && isxdigit(fname[2]))
-    {
-    val = string_catn(val, &size, &ptr, US"=", 1);
-    val = string_catn(val, &size, &ptr, ++fname, 2);
-    fname += 2;
-    }
-  else
-    val = string_catn(val, &size, &ptr, fname++, 1);
-
-val = string_catn(val, &size, &ptr, US"?=", 2);
-val[*len = ptr] = '\0';
-return val;
-}
-
-
 int
 mime_acl_check(uschar *acl, FILE *f, struct mime_boundary_context *context,
     uschar **user_msgptr, uschar **log_msgptr)
@@ -592,10 +565,7 @@
       if (*(p = q)) p++;			/* jump past the ; */
 
 	{
-	uschar * mime_fname = NULL;
-	uschar * mime_fname_rfc2231 = NULL;
-	uschar * mime_filename_charset = NULL;
-	BOOL decoding_failed = FALSE;
+	BOOL header_is_content_disposition = (strncmpic(US"content-disposition:",header,20) == 0);
 
 	/* grab all param=value tags on the remaining line,
 	check if they are interesting */
@@ -606,75 +576,6 @@
 
 	  DEBUG(D_acl) debug_printf_indent("MIME:   considering paramlist '%s'\n", p);
 
-	  if (  !mime_filename
-	     && strncmpic(CUS"content-disposition:", header, 20) == 0
-	     && strncmpic(CUS"filename*", p, 9) == 0
-	     )
-	    {					/* RFC 2231 filename */
-	    uschar * q;
-
-	    /* find value of the filename */
-	    p += 9;
-	    while(*p != '=' && *p) p++;
-	    if (*p) p++;			/* p is filename or NUL */
-	    q = mime_param_val(&p);		/* p now trailing ; or NUL */
-
-	    if (q && *q)
-	      {
-	      uschar * temp_string, * err_msg;
-	      int slen;
-
-	      /* build up an un-decoded filename over successive
-	      filename*= parameters (for use when 2047 decode fails) */
-
-	      mime_fname_rfc2231 = string_sprintf("%#s%s",
-		mime_fname_rfc2231, q);
-
-	      if (!decoding_failed)
-		{
-		int size;
-		if (!mime_filename_charset)
-		  {
-		  uschar * s = 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 (*(p = s)) p++;
-		  while(*p == '\'') p++;	/* p 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);
-
-		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 = rfc2047_decode(temp_string, FALSE, NULL, ' ',
-		  NULL, &err_msg);
-		DEBUG(D_acl) debug_printf_indent("MIME:    plain-name %s\n", temp_string);
-
-		size = Ustrlen(temp_string);
-
-		if (size == slen)
-		  decoding_failed = TRUE;
-		else
-		  /* build up a decoded filename over successive
-		  filename*= parameters */
-
-		  mime_filename = mime_fname = mime_fname
-		    ? string_sprintf("%s%s", mime_fname, temp_string)
-		    : temp_string;
-		}
-	      }
-	    }
-
-	  else
 	    /* look for interesting parameters */
 	    for (mp = mime_parameter_list;
 		 mp < mime_parameter_list + nelem(mime_parameter_list);
@@ -697,6 +598,96 @@
 		mp->name, mh->name, *mp->value);
 
 	      break;			/* done matching param names */
+	      } else {
+                if (header_is_content_disposition && (strncmpic(US"filename=",mp->name,9) == 0)) {
+                  uschar * param_value = NULL;
+                  int param_value_len = 0;
+                  uschar mime_filename_rfc2231[1024];
+                  int size;
+                  BOOL rfc2231_decoded = FALSE;
+
+                  memset(mime_filename_rfc2231, 0, sizeof(mime_filename_rfc2231));
+
+                  // found an RFC 2231 filename?
+                  while (strncmpic(US"filename*",p,9) == 0) {
+                    // find value of the filename
+                    p += 9;
+                    while((*p != '=') && ((p - header) < Ustrlen(header))) p++;
+                    p++;
+                    uschar *q = p;
+                    while((*q != ';') && ((q - header) < Ustrlen(header))) q++;
+                    size = q - p;
+                    uschar *q_prev = q;
+                    q_prev--;
+                    if ((size > 1) && (*p == '"') && (*q_prev == '"')) {
+                      p++;
+                      size -= 2;
+                    }
+                    if (size > 0) {
+                      if (size > sizeof(mime_filename_rfc2231) - Ustrlen(mime_filename_rfc2231) - 1) size = sizeof(mime_filename_rfc2231) - Ustrlen(mime_filename_rfc2231) - 1;
+                      Ustrncpy(mime_filename_rfc2231 + Ustrlen(mime_filename_rfc2231), p, size);
+                    }
+                    p = q; p++;
+                  }
+
+                  if (Ustrlen(mime_filename_rfc2231) > 0) {
+                    uschar mime_filename_charset[24];
+                    uschar *i1 = mime_filename_rfc2231;
+                    uschar *i2 = mime_filename_rfc2231;
+                    uschar *temp_string, *err_msg;
+                    int temp_string_len1 = 0;
+
+                    memset(mime_filename_charset, 0, sizeof(mime_filename_charset));
+
+                    while ((*i1 != '\'') && ((i1 - i2) < Ustrlen(mime_filename_rfc2231)-2)) i1++;
+                    i2 = i1; i2++;
+
+                    if ((i1 - mime_filename_rfc2231 > 0) && (*i1 == '\'') && (*i2 == '\'')) {
+                      size = i1 - mime_filename_rfc2231;
+                      if (size > sizeof(mime_filename_charset) - 1) size = sizeof(mime_filename_charset) - 1;
+                      Ustrncpy(mime_filename_charset, mime_filename_rfc2231, size);
+                      i1 += 2;
+
+                      DEBUG(D_acl) debug_printf_indent("MIME:    charset %s fname '%s'\n",
+                        mime_filename_charset ? mime_filename_charset : US"<NULL>", mime_filename_rfc2231);
+
+                      temp_string = expand_string(string_sprintf(
+                        "=?%s?Q?${sg{%s}{\\N%%([\\dA-Fa-f]{2})\\N}{=\\$1}}?=", mime_filename_charset, i1));
+                      temp_string_len1 = Ustrlen(temp_string);
+                      temp_string = rfc2047_decode(temp_string, FALSE, NULL, 32, NULL, &err_msg);
+                      param_value_len = Ustrlen(temp_string);
+
+                      if ((param_value_len > 0) && (param_value_len != temp_string_len1)) {
+                        rfc2231_decoded = TRUE;
+
+                        param_value = (uschar *)malloc(param_value_len+1);
+                        memset(param_value, 0, param_value_len+1);
+                        Ustrncpy(param_value, temp_string, param_value_len);
+
+                        DEBUG(D_acl) debug_printf_indent("MIME:    plain-name %s\n", param_value);
+
+                        *((uschar **)(mp->value)) = param_value;
+
+                        DEBUG(D_acl) debug_printf_indent(
+                          "MIME:  found %s parameter in %s header, value '%s'\n",
+                          mp->name, mh->name, *mp->value);
+                      }
+                    }
+                    if (!rfc2231_decoded) {
+                      param_value_len = Ustrlen(mime_filename_rfc2231);
+                      param_value = (uschar *)malloc(param_value_len+1);
+                      memset(param_value,0,param_value_len+1);
+                      Ustrncpy(param_value, mime_filename_rfc2231, param_value_len);
+                      param_value = rfc2047_decode(param_value, check_rfc2047_length, NULL, 32, &param_value_len, &err_msg);
+
+                      DEBUG(D_acl) debug_printf_indent(
+                        "MIME:  found %s parameter in %s header, value '%s'\n",
+                        mp->name, mh->name, param_value);
+
+                      *((uschar **)(mp->value)) = param_value;
+                    }
+                  }
+                }
 	      }
 
 
@@ -706,14 +697,6 @@
 	  if (*p) p++;
 	  }				/* param scan on line */
 
-	if (strncmpic(CUS"content-disposition:", header, 20) == 0)
-	  {
-	  if (decoding_failed) mime_filename = mime_fname_rfc2231;
-
-	  DEBUG(D_acl) debug_printf_indent(
-	    "MIME:  found %s parameter in %s header, value is '%s'\n",
-	    "filename", mh->name, mime_filename);
-	  }
 	}
       }
     }