Example #1
0
/**
 * Encodes header as quoted-printable
 *
 * Encode 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 encodeHeader($string)
{
    global $default_charset, $languages, $squirrelmail_language;
    if (isset($languages[$squirrelmail_language]['XTRA_CODE']) && function_exists($languages[$squirrelmail_language]['XTRA_CODE'])) {
        return $languages[$squirrelmail_language]['XTRA_CODE']('encodeheader', $string);
    }
    // Use B encoding for multibyte charsets
    $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);
    $max_l = 75 - strlen($default_charset) - 7;
    $aRet = array();
    $ret = '';
    $iEncStart = $enc_init = false;
    $cur_l = $iOffset = 0;
    for ($i = 0; $i < $j; ++$i) {
        switch ($string[$i]) {
            case '=':
            case '<':
            case '>':
            case ',':
            case '?':
            case '_':
                if ($iEncStart === false) {
                    $iEncStart = $i;
                }
                $cur_l += 3;
                if ($cur_l > $max_l - 2) {
                    /* if there is an stringpart that doesn't need encoding, add it */
                    $aRet[] = substr($string, $iOffset, $iEncStart - $iOffset);
                    $aRet[] = "=?{$default_charset}?Q?{$ret}?=";
                    $iOffset = $i;
                    $cur_l = 0;
                    $ret = '';
                    $iEncStart = false;
                } else {
                    $ret .= sprintf("=%02X", ord($string[$i]));
                }
                break;
            case '(':
            case ')':
                if ($iEncStart !== false) {
                    $aRet[] = substr($string, $iOffset, $iEncStart - $iOffset);
                    $aRet[] = "=?{$default_charset}?Q?{$ret}?=";
                    $iOffset = $i;
                    $cur_l = 0;
                    $ret = '';
                    $iEncStart = false;
                }
                break;
            case ' ':
                if ($iEncStart !== false) {
                    $cur_l++;
                    if ($cur_l > $max_l) {
                        $aRet[] = substr($string, $iOffset, $iEncStart - $iOffset);
                        $aRet[] = "=?{$default_charset}?Q?{$ret}?=";
                        $iOffset = $i;
                        $cur_l = 0;
                        $ret = '';
                        $iEncStart = false;
                    } else {
                        $ret .= '_';
                    }
                }
                break;
            default:
                $k = ord($string[$i]);
                if ($k > 126) {
                    if ($iEncStart === false) {
                        // do not start encoding in the middle of a string, also take the rest of the word.
                        $sLeadString = substr($string, 0, $i);
                        $aLeadString = explode(' ', $sLeadString);
                        $sToBeEncoded = array_pop($aLeadString);
                        $iEncStart = $i - strlen($sToBeEncoded);
                        $ret .= $sToBeEncoded;
                        $cur_l += strlen($sToBeEncoded);
                    }
                    $cur_l += 3;
                    /* first we add the encoded string that reached it's max size */
                    if ($cur_l > $max_l - 2) {
                        $aRet[] = substr($string, $iOffset, $iEncStart - $iOffset);
                        $aRet[] = "=?{$default_charset}?Q?{$ret}?= ";
                        /* the next part is also encoded => separate by space */
                        $cur_l = 3;
                        $ret = '';
                        $iOffset = $i;
                        $iEncStart = $i;
                    }
                    $enc_init = true;
                    $ret .= sprintf("=%02X", $k);
                } else {
                    if ($iEncStart !== false) {
                        $cur_l++;
                        if ($cur_l > $max_l) {
                            $aRet[] = substr($string, $iOffset, $iEncStart - $iOffset);
                            $aRet[] = "=?{$default_charset}?Q?{$ret}?=";
                            $iEncStart = false;
                            $iOffset = $i;
                            $cur_l = 0;
                            $ret = '';
                        } else {
                            $ret .= $string[$i];
                        }
                    }
                }
                break;
        }
    }
    if ($enc_init) {
        if ($iEncStart !== false) {
            $aRet[] = substr($string, $iOffset, $iEncStart - $iOffset);
            $aRet[] = "=?{$default_charset}?Q?{$ret}?=";
        } else {
            $aRet[] = substr($string, $iOffset);
        }
        $string = implode('', $aRet);
    }
    return $string;
}
Example #2
0
File: i18n.php Project: jprice/EHCP
/**
 * Japanese charset extra function
 */
function japanese_charset_xtra()
{
    $ret = func_get_arg(1);
    /* default return value */
    if (function_exists('mb_detect_encoding')) {
        switch (func_get_arg(0)) {
            /* action */
            case 'decode':
                $detect_encoding = @mb_detect_encoding($ret);
                if ($detect_encoding == 'JIS' || $detect_encoding == 'EUC-JP' || $detect_encoding == 'SJIS' || $detect_encoding == 'UTF-8') {
                    $ret = mb_convert_kana(mb_convert_encoding($ret, 'EUC-JP', 'AUTO'), "KV");
                }
                break;
            case 'encode':
                $detect_encoding = @mb_detect_encoding($ret);
                if ($detect_encoding == 'JIS' || $detect_encoding == 'EUC-JP' || $detect_encoding == 'SJIS' || $detect_encoding == 'UTF-8') {
                    $ret = mb_convert_encoding(mb_convert_kana($ret, "KV"), 'JIS', 'AUTO');
                }
                break;
            case 'strimwidth':
                $width = func_get_arg(2);
                $ret = mb_strimwidth($ret, 0, $width, '...');
                break;
            case 'encodeheader':
                /**
                 * First argument ($ret) contains header string.
                 * SquirrelMail ja_JP translation uses euc-jp as internal encoding.
                 * euc-jp stores Japanese letters in 0xA1-0xFE block (source:
                 * JIS X 0208 unicode.org mapping. see euc_jp.php in extra decoding
                 * library). Standard SquirrelMail 8bit test should detect if text
                 * is in euc or in ascii.
                 */
                if (sq_is8bit($ret)) {
                    /**
                     * Minimize dependency on mb_mime_encodeheader(). PHP 4.4.1 bug
                     * and maybe other bugs.
                     *
                     * Convert text from euc-jp (internal encoding) to iso-2022-jp
                     * (commonly used Japanese encoding) with mbstring functions.
                     *
                     * Use SquirrelMail internal B encoding function. 'encodeheader'
                     * XTRA_CODE is executed in encodeHeader() function, so
                     * functions/mime.php (encodeHeaderBase64) and functions/strings.php 
                     * (sq_is8bit) are already loaded.
                     */
                    $ret = encodeHeaderBase64(mb_convert_encoding($ret, 'ISO-2022-JP', 'EUC-JP'), 'iso-2022-jp');
                }
                /**
                 * if text is in ascii, we leave it unchanged. If some ASCII
                 * chars must be encoded, add code here in else statement.
                 */
                break;
            case 'decodeheader':
                $ret = str_replace("\t", "", $ret);
                if (eregi('=\\?([^?]+)\\?(q|b)\\?([^?]+)\\?=', $ret)) {
                    $ret = @mb_decode_mimeheader($ret);
                }
                $ret = @mb_convert_encoding($ret, 'EUC-JP', 'AUTO');
                break;
            case 'downloadfilename':
                $useragent = func_get_arg(2);
                if (strstr($useragent, 'Windows') !== false || strstr($useragent, 'Mac_') !== false) {
                    $ret = mb_convert_encoding($ret, 'SJIS', 'AUTO');
                } else {
                    $ret = mb_convert_encoding($ret, 'EUC-JP', 'AUTO');
                }
                break;
            case 'wordwrap':
                $no_begin = "!%),.:;?]}¡ñ¡ë¡" . "Ç¡É¢ó¡ì¡í¡î¡¢¡£¡¹" . "¡Ó¡Õ¡×¡Ù¡Û¡Í¤¡¤£¤" . "¥¤§¤©¤Ã¤ã¤å¤ç¤î¡«" . "¡¬¡µ¡¶¥¡¥£¥¥¥§¥©¥" . "Ã¥ã¥å¥ç¥î¥õ¥ö¡¦¡¼" . "¡³¡´¡ª¡ó¡Ë¡¤¡¥¡§¡" . "¨¡©¡Ï¡Ñ";
                $no_end = "\\\$([{¡ò\\¡Æ¡È¡Ò¡" . "Ô¡Ö¡Ø¡Ú¡Ì¡ð¡Ê¡Î¡Ð¡ï";
                $wrap = func_get_arg(2);
                if (strlen($ret) >= $wrap && substr($ret, 0, 1) != '>' && strpos($ret, 'http://') === FALSE && strpos($ret, 'https://') === FALSE && strpos($ret, 'ftp://') === FALSE) {
                    $ret = mb_convert_kana($ret, "KV");
                    $line_new = '';
                    $ptr = 0;
                    while ($ptr < strlen($ret) - 1) {
                        $l = mb_strcut($ret, $ptr, $wrap);
                        $ptr += strlen($l);
                        $tmp = $l;
                        $l = mb_strcut($ret, $ptr, 2);
                        while (strlen($l) != 0 && mb_strpos($no_begin, $l) !== FALSE) {
                            $tmp .= $l;
                            $ptr += strlen($l);
                            $l = mb_strcut($ret, $ptr, 1);
                        }
                        $line_new .= $tmp;
                        if ($ptr < strlen($ret) - 1) {
                            $line_new .= "\n";
                        }
                    }
                    $ret = $line_new;
                }
                break;
            case 'utf7-imap_encode':
                $ret = mb_convert_encoding($ret, 'UTF7-IMAP', 'EUC-JP');
                break;
            case 'utf7-imap_decode':
                $ret = mb_convert_encoding($ret, 'EUC-JP', 'UTF7-IMAP');
                break;
        }
    }
    return $ret;
}