Skip to content

Commit

Permalink
- Fix setting charset of attachment filenames (#1487122)
Browse files Browse the repository at this point in the history
  • Loading branch information
alecpl committed Dec 1, 2010
1 parent b46edc0 commit 53604a0
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 90 deletions.
1 change: 1 addition & 0 deletions CHANGELOG
Expand Up @@ -6,6 +6,7 @@ CHANGELOG Roundcube Webmail
- Add 'login_lc' config option for case-insensitive authentication (#1487113)
- Fix window is blur'ed in IE when selecting a message (#1487316)
- Fix cursor position on compose form in Webkit browsers (#1486674)
- Fix setting charset of attachment filenames (#1487122)

RELEASE 0.5-BETA
----------------
Expand Down
2 changes: 1 addition & 1 deletion INSTALL
Expand Up @@ -17,7 +17,7 @@ REQUIREMENTS
- mbstring, fileinfo, mcrypt (optional)
* PEAR packages distributed with Roundcube or external:
- MDB2 2.5.0 or newer
- Mail_Mime 1.7.0 or newer
- Mail_Mime 1.8.1 or newer
- Net_SMTP 1.4.2 or newer
- Auth_SASL 1.0.3 or newer
* php.ini options (see .htaccess file):
Expand Down
57 changes: 34 additions & 23 deletions program/lib/Mail/mime.php
Expand Up @@ -365,30 +365,28 @@ function addHTMLImage($file,
* Adds a file to the list of attachments.
*
* @param string $file The file name of the file to attach
* OR the file contents itself
* or the file contents itself
* @param string $c_type The content type
* @param string $name The filename of the attachment
* Only use if $file is the contents
* @param bool $isfile Whether $file is a filename or not
* Defaults to true
* @param string $encoding The type of encoding to use.
* Defaults to base64.
* Possible values: 7bit, 8bit, base64,
* or quoted-printable.
* @param bool $isfile Whether $file is a filename or not. Defaults to true
* @param string $encoding The type of encoding to use. Defaults to base64.
* Possible values: 7bit, 8bit, base64 or quoted-printable.
* @param string $disposition The content-disposition of this file
* Defaults to attachment.
* Possible values: attachment, inline.
* @param string $charset The character set used in the filename
* of this attachment.
* @param string $charset The character set of attachment's content.
* @param string $language The language of the attachment
* @param string $location The RFC 2557.4 location of the attachment
* @param string $n_encoding Encoding for attachment name (Content-Type)
* @param string $n_encoding Encoding of the attachment's name in Content-Type
* By default filenames are encoded using RFC2231 method
* Here you can set RFC2047 encoding (quoted-printable
* or base64) instead
* @param string $f_encoding Encoding for attachment filename (Content-Disposition)
* See $n_encoding description
* @param string $f_encoding Encoding of the attachment's filename
* in Content-Disposition header.
* @param string $description Content-Description header
* @param string $h_charset The character set of the headers e.g. filename
* If not specified, $charset will be used
*
* @return mixed True on success or PEAR_Error object
* @access public
Expand All @@ -404,7 +402,8 @@ function addAttachment($file,
$location = '',
$n_encoding = null,
$f_encoding = null,
$description = ''
$description = '',
$h_charset = null
) {
$bodyfile = null;

Expand Down Expand Up @@ -437,14 +436,15 @@ function addAttachment($file,
'body_file' => $bodyfile,
'name' => $filename,
'c_type' => $c_type,
'encoding' => $encoding,
'charset' => $charset,
'encoding' => $encoding,
'language' => $language,
'location' => $location,
'disposition' => $disposition,
'description' => $description,
'name_encoding' => $n_encoding,
'filename_encoding' => $f_encoding
'filename_encoding' => $f_encoding,
'headers_charset' => $h_charset,
);

return true;
Expand Down Expand Up @@ -621,7 +621,7 @@ function &_addHtmlImagePart(&$obj, $value)
$params['content_type'] = $value['c_type'];
$params['encoding'] = 'base64';
$params['disposition'] = 'inline';
$params['dfilename'] = $value['name'];
$params['filename'] = $value['name'];
$params['cid'] = $value['cid'];
$params['body_file'] = $value['body_file'];
$params['eol'] = $this->_build_params['eol'];
Expand Down Expand Up @@ -650,19 +650,25 @@ function &_addHtmlImagePart(&$obj, $value)
function &_addAttachmentPart(&$obj, $value)
{
$params['eol'] = $this->_build_params['eol'];
$params['dfilename'] = $value['name'];
$params['filename'] = $value['name'];
$params['encoding'] = $value['encoding'];
$params['content_type'] = $value['c_type'];
$params['body_file'] = $value['body_file'];
$params['disposition'] = isset($value['disposition']) ?
$value['disposition'] : 'attachment';
if ($value['charset']) {

// content charset
if (!empty($value['charset'])) {
$params['charset'] = $value['charset'];
}
if ($value['language']) {
// headers charset (filename, description)
if (!empty($value['headers_charset'])) {
$params['headers_charset'] = $value['headers_charset'];
}
if (!empty($value['language'])) {
$params['language'] = $value['language'];
}
if ($value['location']) {
if (!empty($value['location'])) {
$params['location'] = $value['location'];
}
if (!empty($value['name_encoding'])) {
Expand Down Expand Up @@ -1387,18 +1393,23 @@ function _contentHeaders()

if ($headers['Content-Type'] == 'text/plain') {
// single-part message: add charset and encoding
$charset = 'charset=' . $this->_build_params['text_charset'];
// place charset parameter in the same line, if possible
// 26 = strlen("Content-Type: text/plain; ")
$headers['Content-Type']
.= ";$eol charset=" . $this->_build_params['text_charset'];
.= (strlen($charset) + 26 <= 76) ? "; $charset" : ";$eol $charset";
$headers['Content-Transfer-Encoding']
= $this->_build_params['text_encoding'];
} else if ($headers['Content-Type'] == 'text/html') {
// single-part message: add charset and encoding
$charset = 'charset=' . $this->_build_params['html_charset'];
// place charset parameter in the same line, if possible
$headers['Content-Type']
.= ";$eol charset=" . $this->_build_params['html_charset'];
.= (strlen($charset) + 25 <= 76) ? "; $charset" : ";$eol $charset";
$headers['Content-Transfer-Encoding']
= $this->_build_params['html_encoding'];
} else {
// multipart message: add charset and boundary
// multipart message: and boundary
if (!empty($this->_build_params['boundary'])) {
$boundary = $this->_build_params['boundary'];
} else if (!empty($this->_headers['Content-Type'])
Expand Down
104 changes: 40 additions & 64 deletions program/lib/Mail/mimePart.php
Expand Up @@ -141,17 +141,19 @@ class Mail_mimePart
* content_type - The content type for this part eg multipart/mixed
* encoding - The encoding to use, 7bit, 8bit,
* base64, or quoted-printable
* charset - Content character set
* cid - Content ID to apply
* disposition - Content disposition, inline or attachment
* dfilename - Filename parameter for content disposition
* description - Content description
* charset - Character set to use
* name_encoding - Encoding for attachment name (Content-Type)
* name_encoding - Encoding of the attachment name (Content-Type)
* By default filenames are encoded using RFC2231
* Here you can set RFC2047 encoding (quoted-printable
* or base64) instead
* filename_encoding - Encoding for attachment filename (Content-Disposition)
* filename_encoding - Encoding of the attachment filename (Content-Disposition)
* See 'name_encoding'
* headers_charset - Charset of the headers e.g. filename, description.
* If not set, 'charset' will be used
* eol - End of line sequence. Default: "\r\n"
* body_file - Location of file with part's body (instead of $body)
*
Expand All @@ -165,14 +167,8 @@ function Mail_mimePart($body = '', $params = array())
$this->_eol = MAIL_MIMEPART_CRLF;
}

$c_type = array();
$c_disp = array();
foreach ($params as $key => $value) {
switch ($key) {
case 'content_type':
$c_type['type'] = $value;
break;

case 'encoding':
$this->_encoding = $value;
$headers['Content-Transfer-Encoding'] = $value;
Expand All @@ -182,29 +178,6 @@ function Mail_mimePart($body = '', $params = array())
$headers['Content-ID'] = '<' . $value . '>';
break;

case 'disposition':
$c_disp['disp'] = $value;
break;

case 'dfilename':
$c_disp['filename'] = $value;
$c_type['name'] = $value;
break;

case 'description':
$headers['Content-Description'] = $value;
break;

case 'charset':
$c_type['charset'] = $value;
$c_disp['charset'] = $value;
break;

case 'language':
$c_type['language'] = $value;
$c_disp['language'] = $value;
break;

case 'location':
$headers['Content-Location'] = $value;
break;
Expand All @@ -216,53 +189,56 @@ function Mail_mimePart($body = '', $params = array())
}

// Default content-type
if (empty($c_type['type'])) {
$c_type['type'] = 'text/plain';
if (empty($params['content_type'])) {
$params['content_type'] = 'text/plain';
}

// Content-Type
if (!empty($c_type['type'])) {
$headers['Content-Type'] = $c_type['type'];
if (!empty($c_type['charset'])) {
$charset = "charset={$c_type['charset']}";
// place charset parameter in the same line, if possible
if ((strlen($headers['Content-Type']) + strlen($charset) + 16) <= 76) {
$headers['Content-Type'] .= '; ';
} else {
$headers['Content-Type'] .= ';' . $this->_eol . ' ';
}
$headers['Content-Type'] .= $charset;
$headers['Content-Type'] = $params['content_type'];
if (!empty($params['charset'])) {
$charset = "charset={$params['charset']}";
// place charset parameter in the same line, if possible
if ((strlen($headers['Content-Type']) + strlen($charset) + 16) <= 76) {
$headers['Content-Type'] .= '; ';
} else {
$headers['Content-Type'] .= ';' . $this->_eol . ' ';
}
if (!empty($c_type['name'])) {
$headers['Content-Type'] .= ';' . $this->_eol;
$headers['Content-Type'] .= $this->_buildHeaderParam(
'name', $c_type['name'],
isset($c_type['charset']) ? $c_type['charset'] : 'US-ASCII',
isset($c_type['language']) ? $c_type['language'] : null,
isset($params['name_encoding']) ? $params['name_encoding'] : null
);
$headers['Content-Type'] .= $charset;

// Default headers charset
if (!isset($params['headers_charset'])) {
$params['headers_charset'] = $params['charset'];
}
}
if (!empty($params['filename'])) {
$headers['Content-Type'] .= ';' . $this->_eol;
$headers['Content-Type'] .= $this->_buildHeaderParam(
'name', $params['filename'],
!empty($params['headers_charset']) ? $params['headers_charset'] : 'US-ASCII',
!empty($params['language']) ? $params['language'] : null,
!empty($params['name_encoding']) ? $params['name_encoding'] : null
);
}

// Content-Disposition
if (!empty($c_disp['disp'])) {
$headers['Content-Disposition'] = $c_disp['disp'];
if (!empty($c_disp['filename'])) {
if (!empty($params['disposition'])) {
$headers['Content-Disposition'] = $params['disposition'];
if (!empty($params['filename'])) {
$headers['Content-Disposition'] .= ';' . $this->_eol;
$headers['Content-Disposition'] .= $this->_buildHeaderParam(
'filename', $c_disp['filename'],
isset($c_disp['charset']) ? $c_disp['charset'] : 'US-ASCII',
isset($c_disp['language']) ? $c_disp['language'] : null,
isset($params['filename_encoding']) ? $params['filename_encoding'] : null
'filename', $params['filename'],
!empty($params['headers_charset']) ? $params['headers_charset'] : 'US-ASCII',
!empty($params['language']) ? $params['language'] : null,
!empty($params['filename_encoding']) ? $params['filename_encoding'] : null
);
}
}

if (!empty($headers['Content-Description'])) {
if (!empty($params['description'])) {
$headers['Content-Description'] = $this->encodeHeader(
'Content-Description', $headers['Content-Description'],
isset($c_type['charset']) ? $c_type['charset'] : 'US-ASCII',
isset($params['name_encoding']) ? $params['name_encoding'] : 'quoted-printable',
'Content-Description', $params['description'],
!empty($params['headers_charset']) ? $params['headers_charset'] : 'US-ASCII',
!empty($params['name_encoding']) ? $params['name_encoding'] : 'quoted-printable',
$this->_eol
);
}
Expand Down
5 changes: 3 additions & 2 deletions program/steps/mail/sendmail.inc
Expand Up @@ -513,9 +513,10 @@ if (is_array($_SESSION['compose']['attachments']))
($attachment['data'] ? false : true),
($ctype == 'message/rfc822' ? '8bit' : 'base64'),
($ctype == 'message/rfc822' ? 'inline' : 'attachment'),
$message_charset, '', '',
'', '', '',
$CONFIG['mime_param_folding'] ? 'quoted-printable' : NULL,
$CONFIG['mime_param_folding'] == 2 ? 'quoted-printable' : NULL
$CONFIG['mime_param_folding'] == 2 ? 'quoted-printable' : NULL,
'', RCMAIL_CHARSET
);
}
}
Expand Down

0 comments on commit 53604a0

Please sign in to comment.