* Encodes header
*
* Function uses XTRA_CODE _encodeheader function, if such function exists.
- *
- * mb_encode_mimeheader is used, if function is present, 50% or more bytes
- * are 8bit and multibyte character set is used.
*
* Function uses Q encoding by default and encodes a string according to RFC
* 1522 for use in headers if it contains 8-bit characters or anything that
* looks like it should be encoded.
*
+ * Function switches to B encoding and encodeHeaderBase64() function, if
+ * string is 8bit and multibyte character set supported by mbstring extension
+ * is used. It can cause E_USER_NOTICE errors, if interface is used with
+ * multibyte character set unsupported by mbstring extension.
+ *
* @param string $string header string, that has to be encoded
* @return string quoted-printable encoded string
+ * @todo make $mb_charsets system wide constant
*/
function encodeHeader ($string) {
global $default_charset, $languages, $squirrelmail_language;
}
// Use B encoding for multibyte charsets
- /*
- $mb_charsets = array('utf-8','big-5','gb2313','euc-kr');
- if (function_exists('mb_encode_mimeheader') &&
- in_array($default_charset,$mb_charsets) &&
- in_array($default_charset,sq_mb_list_encodings())) {
- return mb_encode_mimeheader($string,$default_charset,'B',"\r\n");
- }*/
+ $mb_charsets = array('utf-8','big5','gb2313','euc-kr');
+ if (in_array($default_charset,$mb_charsets) &&
+ in_array($default_charset,sq_mb_list_encodings()) &&
+ sq_is8bit($string)) {
+ return encodeHeaderBase64($string,$default_charset);
+ } elseif (in_array($default_charset,$mb_charsets) &&
+ sq_is8bit($string) &&
+ ! in_array($default_charset,sq_mb_list_encodings())) {
+ // Add E_USER_NOTICE error here (can cause 'Cannot add header information' warning in compose.php)
+ // trigger_error('encodeHeader: Multibyte character set unsupported by mbstring extension.',E_USER_NOTICE);
+ }
// Encode only if the string contains 8-bit characters or =?
$j = strlen($string);
return $string;
}
+/**
+ * Encodes string according to rfc2047 B encoding header formating rules
+ *
+ * It is recommended way to encode headers with character sets that store
+ * symbols in more than one byte.
+ *
+ * Function requires mbstring support. If required mbstring functions are missing,
+ * function returns false and sets E_USER_WARNING level error message.
+ *
+ * Minimal requirements - php 4.0.6 with mbstring extension. Please note,
+ * that mbstring functions will generate E_WARNING errors, if unsupported
+ * character set is used. mb_encode_mimeheader function provided by php
+ * mbstring extension is not used in order to get better control of header
+ * encoding.
+ *
+ * Used php code functions - function_exists(), trigger_error(), strlen()
+ * (is used with charset names and base64 strings). Used php mbstring
+ * functions - mb_strlen and mb_substr.
+ *
+ * Related documents: rfc 2045 (BASE64 encoding), rfc 2047 (mime header
+ * encoding), rfc 2822 (header folding)
+ *
+ * @param string $string header string that must be encoded
+ * @param string $charset character set. Must be supported by mbstring extension.
+ * Use sq_mb_list_encodings() to detect supported charsets.
+ * @return string string encoded according to rfc2047 B encoding formating rules
+ * @since 1.5.1
+ * @todo First header line can be wrapped to $iMaxLength - $HeaderFieldLength - 1
+ * @todo Do we want to control max length of header?
+ * @todo Do we want to control EOL (end-of-line) marker?
+ * @todo Do we want to translate error message?
+ */
+function encodeHeaderBase64($string,$charset) {
+ /**
+ * Check mbstring function requirements.
+ */
+ if (! function_exists('mb_strlen') ||
+ ! function_exists('mb_substr')) {
+ // set E_USER_WARNING
+ trigger_error('encodeHeaderBase64: Required mbstring functions are missing.',E_USER_WARNING);
+ // return false
+ return false;
+ }
+
+ // initial return array
+ $aRet = array();
+
+ /**
+ * header length = 75 symbols max (same as in encodeHeader)
+ * remove $charset length
+ * remove =? ? ?= (5 chars)
+ * remove 2 more chars (\r\n ?)
+ */
+ $iMaxLength = 75 - strlen($charset) - 7;
+
+ // set first character position
+ $iStartCharNum = 0;
+
+ // loop through all characters. count characters and not bytes.
+ for ($iCharNum=1; $iCharNum<=mb_strlen($string,$charset); $iCharNum++) {
+ // encode string from starting character to current character.
+ $encoded_string = base64_encode(mb_substr($string,$iStartCharNum,$iCharNum-$iStartCharNum,$charset));
+
+ // Check encoded string length
+ if(strlen($encoded_string)>$iMaxLength) {
+ // if string exceeds max length, reduce number of encoded characters and add encoded string part to array
+ $aRet[] = base64_encode(mb_substr($string,$iStartCharNum,$iCharNum-$iStartCharNum-1,$charset));
+
+ // set new starting character
+ $iStartCharNum = $iCharNum-1;
+
+ // encode last char (in case it is last character in string)
+ $encoded_string = base64_encode(mb_substr($string,$iStartCharNum,$iCharNum-$iStartCharNum,$charset));
+ } // if string is shorter than max length - add next character
+ }
+
+ // add last encoded string to array
+ $aRet[] = $encoded_string;
+
+ // set initial return string
+ $sRet = '';
+
+ // loop through encoded strings
+ foreach($aRet as $string) {
+ // TODO: Do we want to control EOL (end-of-line) marker
+ if ($sRet!='') $sRet.= " ";
+
+ // add header tags and encoded string to return string
+ $sRet.= '=?'.$charset.'?B?'.$string.'?=';
+ }
+
+ return $sRet;
+}
+
/* This function trys to locate the entity_id of a specific mime element */
function find_ent_id($id, $message) {
for ($i = 0, $ret = ''; $ret == '' && $i < count($message->entities); $i++) {