diff -urN ../exim-4.84.orig/src/mime.c ./src/mime.c --- ../exim-4.84.orig/src/mime.c 2014-11-12 02:53:25.000000000 +0200 +++ ./src/mime.c 2014-11-12 02:53:57.000000000 +0200 @@ -588,6 +588,11 @@ /* make p point to the next character after the closing ';' */ p += (header_value_len+1); +{ + int header_is_content_disposition = 0; + + if (strncmpic("content-disposition:",header,20) == 0) header_is_content_disposition = 1; + /* grab all param=value tags on the remaining line, check if they are interesting */ NEXT_PARAM_SEARCH: while (*p != 0) @@ -634,6 +639,78 @@ *mp->value = param_value; p += (mp->namelen + param_value_len + 1); goto NEXT_PARAM_SEARCH; + } else { + if (header_is_content_disposition && (strncmpic("filename=",mp->name,9) == 0)) { + uschar mime_filename_rfc2231[1024]; + int size; + int decoded = 0; + + memset(mime_filename_rfc2231, 0, sizeof(mime_filename_rfc2231)); + + // found an RFC 2231 filename? + while (strncmpic("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; + 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; + int temp_string_len2 = 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; + + 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, &temp_string_len2, &err_msg); + param_value_len = Ustrlen(temp_string); + + if ((param_value_len > 0) && (param_value_len != temp_string_len1)) { + decoded = 1; + + 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_printf("Found %s MIME parameter in %s header, value is '%s'\n", mp->name, mime_header_list[i].name, param_value); + *((uschar **)(mp->value)) = param_value; + goto NEXT_PARAM_SEARCH; + } + } + if (!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, ¶m_value_len, &err_msg); + debug_printf("Found %s MIME parameter in %s header, value is '%s'\n", mp->name, mime_header_list[i].name, param_value); + *((uschar **)(mp->value)) = param_value; + goto NEXT_PARAM_SEARCH; + } + } + } } } /* There is something, but not one of our interesting parameters. @@ -641,6 +718,9 @@ while(*p != ';') p++; p++; } + +} + } } }