diff options
Diffstat (limited to 'program/lib/Mail/mimePart.php')
-rw-r--r-- | program/lib/Mail/mimePart.php | 112 |
1 files changed, 99 insertions, 13 deletions
diff --git a/program/lib/Mail/mimePart.php b/program/lib/Mail/mimePart.php index bd3047724..9b9f26cc3 100644 --- a/program/lib/Mail/mimePart.php +++ b/program/lib/Mail/mimePart.php @@ -182,13 +182,16 @@ class Mail_mimePart { } } + if (isset($contentType['type'])) { $headers['Content-Type'] = $contentType['type']; if (isset($contentType['name'])) { $headers['Content-Type'] .= ';' . MAIL_MIMEPART_CRLF; - $headers['Content-Type'] .= $this->_buildHeaderParam('name', $contentType['name'], - isset($contentType['charset']) ? $contentType['charset'] : 'US-ASCII', - isset($contentType['language']) ? $contentType['language'] : NULL); + $headers['Content-Type'] .= + $this->_buildHeaderParam('name', $contentType['name'], + isset($contentType['charset']) ? $contentType['charset'] : 'US-ASCII', + isset($contentType['language']) ? $contentType['language'] : NULL, + isset($params['name-encoding']) ? $params['name-encoding'] : NULL); } elseif (isset($contentType['charset'])) { $headers['Content-Type'] .= "; charset=\"{$contentType['charset']}\""; } @@ -199,15 +202,14 @@ class Mail_mimePart { $headers['Content-Disposition'] = $contentDisp['disp']; if (isset($contentDisp['filename'])) { $headers['Content-Disposition'] .= ';' . MAIL_MIMEPART_CRLF; - $headers['Content-Disposition'] .= $this->_buildHeaderParam('filename', $contentDisp['filename'], - isset($contentDisp['charset']) ? $contentDisp['charset'] : 'US-ASCII', - isset($contentDisp['language']) ? $contentDisp['language'] : NULL); + $headers['Content-Disposition'] .= + $this->_buildHeaderParam('filename', $contentDisp['filename'], + isset($contentDisp['charset']) ? $contentDisp['charset'] : 'US-ASCII', + isset($contentDisp['language']) ? $contentDisp['language'] : NULL, + isset($params['filename-encoding']) ? $params['filename-encoding'] : NULL); } } - - - - + // Default content-type if (!isset($headers['Content-Type'])) { $headers['Content-Type'] = 'text/plain'; @@ -388,21 +390,25 @@ class Mail_mimePart { * @param $value The value of the paramter * @param $charset The characterset of $value * @param $language The language used in $value + * @param $paramEnc Parameter encoding type * @param $maxLength The maximum length of a line. Defauls to 78 * * @access private */ - function _buildHeaderParam($name, $value, $charset=NULL, $language=NULL, $maxLength=78) + function _buildHeaderParam($name, $value, $charset=NULL, $language=NULL, $paramEnc=NULL, $maxLength=78) { // RFC 2183/2184/2822: // value needs encoding if contains non-ASCII chars or is longer than 78 chars - if (!preg_match('#[^\x20-\x7E]#', $value)) { // ASCII $quoted = addcslashes($value, '\\"'); if (strlen($name) + strlen($quoted) + 6 <= $maxLength) return " {$name}=\"{$quoted}\"; "; } + // use quoted-printable/base64 encoding (RFC2047) + if ($paramEnc == 'quoted-printable' || $paramEnc == 'base64') + return $this->_buildRFC2047Param($name, $value, $charset, $paramEnc); + $encValue = preg_replace('#([^\x20-\x7E])#e', '"%" . strtoupper(dechex(ord("\1")))', $value); $value = "$charset'$language'$encValue"; @@ -413,7 +419,7 @@ class Mail_mimePart { $preLength = strlen(" {$name}*0*=\""); $sufLength = strlen("\";"); - $maxLength = MAX(16, $maxLength - $preLength - $sufLength - 2); + $maxLength = max(16, $maxLength - $preLength - $sufLength - 2); $maxLengthReg = "|(.{0,$maxLength}[^\%][^\%])|"; $headers = array(); @@ -433,4 +439,84 @@ class Mail_mimePart { $headers = implode(MAIL_MIMEPART_CRLF, $headers) . ';'; return $headers; } + + /** + * Encodes header parameter as per RFC2047 if needed (values too long will be truncated) + * + * @param string $name The parameter name + * @param string $value The parameter value + * @param string $charset The parameter charset + * @param string $encoding Encoding type (quoted-printable or base64) + * @param int $maxLength Encoded parameter max length (75 is the value specified in the RFC) + * + * @return string Parameter line + * @access private + */ + function _buildRFC2047Param($name, $value, $charset, $encoding='quoted-printable', $maxLength=75) + { + if (!preg_match('#([^\x20-\x7E]){1}#', $value)) + { + $quoted = addcslashes($value, '\\"'); + $maxLength = $maxLength - 6; + if (strlen($quoted) > $maxLength) + { + // truncate filename leaving extension + $ext = strrchr($quoted, '.'); + $quoted = substr($quoted, 0, $maxLength - strlen($ext)); + // remove backslashes from the end of filename + preg_replace('/[\\\\]+$/', '', $quoted); + $quoted .= $ext; + } + } + else if ($encoding == 'base64') + { + $ext = strrchr($value, '.'); + $value = substr($value, 0, strlen($value) - strlen($ext)); + + $ext = base64_encode($ext); + $value = base64_encode($value); + + $prefix = '=?' . $charset . '?B?'; + $suffix = '?='; + $maxLength = $maxLength - strlen($prefix . $suffix) - strlen($ext) - 2; + + //We can cut base64 every 4 characters, so the real max + //we can get must be rounded down. + $maxLength = $maxLength - ($maxLength % 4); + $quoted = $prefix . substr($value, 0, $maxLength) . $ext . $suffix; + } + else // quoted-printable + { + $ext = strrchr($value, '.'); + $value = substr($value, 0, strlen($value) - strlen($ext)); + + // Replace all special characters used by the encoder. + $search = array('=', '_', '?', ' '); + $replace = array('=3D', '=5F', '=3F', '_'); + $ext = str_replace($search, $replace, $ext); + $value = str_replace($search, $replace, $value); + + // Replace all extended characters (\x80-xFF) with their + // ASCII values. + $ext = preg_replace('/([\x80-\xFF])/e', + '"=" . strtoupper(dechex(ord("\1")))', $ext); + $value = preg_replace('/([\x80-\xFF])/e', + '"=" . strtoupper(dechex(ord("\1")))', $value); + + $prefix = '=?' . $charset . '?Q?'; + $suffix = '?='; + + $maxLength = $maxLength - strlen($prefix . $suffix) - strlen($ext) - 2; + + // Truncate QP-encoded text at $maxLength + // but not break any encoded letters. + if(preg_match("/^(.{0,$maxLength}[^\=][^\=])/", $value, $matches)) + $value = $matches[1]; + + $quoted = $prefix . $value . $ext . $suffix; + } + + return " {$name}=\"{$quoted}\"; "; + } + } // End of class |