- Support UTF-7 encoding in messages (#1485832)
| | |
| | | CHANGELOG RoundCube Webmail |
| | | =========================== |
| | | |
| | | - Support UTF-7 encoding in messages (#1485832) |
| | | - Better support for malformed character names (#1485758) |
| | | - Added possibility to encrypt received header, option 'http_received_header_encrypt', |
| | | added some more logic in encrypt/decrypt functions for security |
| | |
| | | |
| | | // convert charset using mbstring module |
| | | if ($mbstring_loaded) { |
| | | $aliases['UTF-7'] = 'UTF7-IMAP'; |
| | | $aliases['WINDOWS-1257'] = 'ISO-8859-13'; |
| | | |
| | | if (is_null($mbstring_list)) { |
| | |
| | | if (in_array($mb_from, $mbstring_list) && in_array($mb_to, $mbstring_list)) { |
| | | if (mb_check_encoding($str, $mb_from) && ($out = mb_convert_encoding($str, $mb_to, $mb_from))) |
| | | return $out; |
| | | else |
| | | // return here, encoding supported, but string is invalid |
| | | return $str; |
| | | } |
| | | } |
| | | |
| | |
| | | $conv = new utf8(); |
| | | |
| | | // convert string to UTF-8 |
| | | if ($from == 'UTF-7') { |
| | | if ($_str = utf7_to_utf8($str)) |
| | | $str = $_str; |
| | | else |
| | | if ($to == 'UTF-8') { |
| | | if ($from == 'UTF7-IMAP') { |
| | | if ($_str = utf7_to_utf8($str)) |
| | | $str = $_str; |
| | | else |
| | | $error = true; |
| | | } |
| | | else if ($from == 'UTF-7') { |
| | | if ($_str = rcube_utf7_to_utf8($str)) |
| | | $str = $_str; |
| | | else |
| | | $error = true; |
| | | } |
| | | else if (($from == 'ISO-8859-1') && function_exists('utf8_encode')) { |
| | | $str = utf8_encode($str); |
| | | } |
| | | else if ($from != 'UTF-8' && $conv) { |
| | | $conv->loadCharset($from); |
| | | $str = $conv->strToUtf8($str); |
| | | } |
| | | else if ($from != 'UTF-8') |
| | | $error = true; |
| | | } |
| | | else if (($from == 'ISO-8859-1') && function_exists('utf8_encode')) { |
| | | $str = utf8_encode($str); |
| | | } |
| | | else if ($from != 'UTF-8' && $conv) { |
| | | $conv->loadCharset($from); |
| | | $str = $conv->strToUtf8($str); |
| | | } |
| | | else if ($from != 'UTF-8') |
| | | $error = true; |
| | | |
| | | |
| | | // encode string for output |
| | | if ($to == 'UTF-7') { |
| | | return utf8_to_utf7($str); |
| | | } |
| | | else if ($to == 'ISO-8859-1' && function_exists('utf8_decode')) { |
| | | return utf8_decode($str); |
| | | } |
| | | else if ($to != 'UTF-8' && $conv) { |
| | | $conv->loadCharset($to); |
| | | return $conv->utf8ToStr($str); |
| | | } |
| | | else if ($to != 'UTF-8') { |
| | | $error = true; |
| | | if ($from == 'UTF-8') { |
| | | // @TODO: we need a function for UTF-7 (RFC2152) conversion |
| | | if ($to == 'UTF7-IMAP' || $to == 'UTF-7') { |
| | | if ($_str = utf8_to_utf7($str)) |
| | | $str = $_str; |
| | | else |
| | | $error = true; |
| | | } |
| | | else if ($to == 'ISO-8859-1' && function_exists('utf8_decode')) { |
| | | return utf8_decode($str); |
| | | } |
| | | else if ($to != 'UTF-8' && $conv) { |
| | | $conv->loadCharset($to); |
| | | return $conv->utf8ToStr($str); |
| | | } |
| | | else if ($to != 'UTF-8') { |
| | | $error = true; |
| | | } |
| | | } |
| | | |
| | | // report error |
| | |
| | | 'ISO88598I' => 'ISO-8859-8', |
| | | 'KSC56011987' => 'EUC-KR', |
| | | 'UNICODE' => 'UTF-8', |
| | | 'UTF7IMAP' => 'UTF7-IMAP' |
| | | ); |
| | | |
| | | $str = preg_replace('/[^a-z0-9]/i', '', $charset); |
| | |
| | | |
| | | return $charset; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Converts string from standard UTF-7 (RFC 2152) to UTF-8. |
| | | * |
| | | * @param string Input string |
| | | * @return The converted string |
| | | */ |
| | | function rcube_utf7_to_utf8($str) |
| | | { |
| | | $Index_64 = array( |
| | | 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, |
| | | 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, |
| | | 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0, |
| | | 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0, |
| | | 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, |
| | | 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, |
| | | 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, |
| | | 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, |
| | | ); |
| | | |
| | | $u7len = strlen($str); |
| | | $str = strval($str); |
| | | $res = ''; |
| | | |
| | | for ($i=0; $u7len > 0; $i++, $u7len--) |
| | | { |
| | | $u7 = $str[$i]; |
| | | if ($u7 == '+') |
| | | { |
| | | $i++; |
| | | $u7len--; |
| | | $ch = ''; |
| | | |
| | | for (; $u7len > 0; $i++, $u7len--) |
| | | { |
| | | $u7 = $str[$i]; |
| | | |
| | | if (!$Index_64[ord($u7)]) |
| | | break; |
| | | |
| | | $ch .= $u7; |
| | | } |
| | | |
| | | if ($ch == '') { |
| | | if ($u7 == '-') |
| | | $res .= '+'; |
| | | continue; |
| | | } |
| | | |
| | | $res .= rcube_utf16_to_utf8(base64_decode($ch)); |
| | | } |
| | | else |
| | | { |
| | | $res .= $u7; |
| | | } |
| | | } |
| | | |
| | | return $res; |
| | | } |
| | | |
| | | /** |
| | | * Converts string from UTF-16 to UTF-8 (helper for utf-7 to utf-8 conversion) |
| | | * |
| | | * @param string Input string |
| | | * @return The converted string |
| | | */ |
| | | function rcube_utf16_to_utf8($str) |
| | | { |
| | | $len = strlen($str); |
| | | $dec = ''; |
| | | |
| | | for ($i = 0; $i < $len; $i += 2) { |
| | | $c = ord($str[$i]) << 8 | ord($str[$i + 1]); |
| | | if ($c >= 0x0001 && $c <= 0x007F) { |
| | | $dec .= chr($c); |
| | | } else if ($c > 0x07FF) { |
| | | $dec .= chr(0xE0 | (($c >> 12) & 0x0F)); |
| | | $dec .= chr(0x80 | (($c >> 6) & 0x3F)); |
| | | $dec .= chr(0x80 | (($c >> 0) & 0x3F)); |
| | | } else { |
| | | $dec .= chr(0xC0 | (($c >> 6) & 0x1F)); |
| | | $dec .= chr(0x80 | (($c >> 0) & 0x3F)); |
| | | } |
| | | } |
| | | return $dec; |
| | | } |
| | | |
| | | |
| | | /** |
| | |
| | | if ($enctype=='js') |
| | | { |
| | | if ($charset!='UTF-8') |
| | | $str = rcube_charset_convert($str, RCMAIL_CHARSET,$charset); |
| | | $str = rcube_charset_convert($str, RCMAIL_CHARSET, $charset); |
| | | |
| | | return preg_replace(array("/\r?\n/", "/\r/", '/<\\//'), array('\n', '\n', '<\\/'), strtr($str, $js_rep_table)); |
| | | } |
| | |
| | | if (!isset($arrFolders[$currentFolder])) { |
| | | $arrFolders[$currentFolder] = array( |
| | | 'id' => $path, |
| | | 'name' => rcube_charset_convert($currentFolder, 'UTF-7'), |
| | | 'name' => rcube_charset_convert($currentFolder, 'UTF7-IMAP'), |
| | | 'virtual' => $virtual, |
| | | 'folders' => array()); |
| | | } |
| | |
| | | if ($folder_class = rcmail_folder_classname($name)) |
| | | return rcube_label($folder_class); |
| | | else |
| | | return rcube_charset_convert($name, 'UTF-7'); |
| | | return rcube_charset_convert($name, 'UTF7-IMAP'); |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | // fix default imap folders encoding |
| | | foreach (array('drafts_mbox', 'junk_mbox', 'sent_mbox', 'trash_mbox') as $folder) |
| | | $this->prop[$folder] = rcube_charset_convert($this->prop[$folder], RCMAIL_CHARSET, 'UTF-7'); |
| | | $this->prop[$folder] = rcube_charset_convert($this->prop[$folder], RCMAIL_CHARSET, 'UTF7-IMAP'); |
| | | |
| | | if (!empty($this->prop['default_imap_folders'])) |
| | | foreach ($this->prop['default_imap_folders'] as $n => $folder) |
| | | $this->prop['default_imap_folders'][$n] = rcube_charset_convert($folder, RCMAIL_CHARSET, 'UTF-7'); |
| | | $this->prop['default_imap_folders'][$n] = rcube_charset_convert($folder, RCMAIL_CHARSET, 'UTF7-IMAP'); |
| | | |
| | | // set PHP error logging according to config |
| | | if ($this->prop['debug_level'] & 1) { |
| | |
| | | if (($p = array_search(strtolower($folder), $this->default_folders_lc)) !== false && !$a_defaults[$p]) |
| | | $a_defaults[$p] = $folder; |
| | | else |
| | | $folders[$folder] = rc_strtolower(rcube_charset_convert($folder, 'UTF-7')); |
| | | $folders[$folder] = rc_strtolower(rcube_charset_convert($folder, 'UTF7-IMAP')); |
| | | } |
| | | |
| | | // sort folders and place defaults on the top |
| | |
| | | |
| | | */ |
| | | |
| | | // WARNING: folder names in UI are encoded with UTF-8 |
| | | // WARNING: folder names in UI are encoded with RCMAIL_CHARSET |
| | | |
| | | // init IMAP connection |
| | | $RCMAIL->imap_init(true); |
| | |
| | | // subscribe to one or more mailboxes |
| | | if ($RCMAIL->action=='subscribe') |
| | | { |
| | | if ($mbox = get_input_value('_mbox', RCUBE_INPUT_POST, false, 'UTF-7')) |
| | | if ($mbox = get_input_value('_mbox', RCUBE_INPUT_POST, false, 'UTF7-IMAP')) |
| | | $IMAP->subscribe(array($mbox)); |
| | | } |
| | | |
| | | // unsubscribe one or more mailboxes |
| | | else if ($RCMAIL->action=='unsubscribe') |
| | | { |
| | | if ($mbox = get_input_value('_mbox', RCUBE_INPUT_POST, false, 'UTF-7')) |
| | | if ($mbox = get_input_value('_mbox', RCUBE_INPUT_POST, false, 'UTF7-IMAP')) |
| | | $IMAP->unsubscribe(array($mbox)); |
| | | } |
| | | |
| | |
| | | { |
| | | if (!empty($_POST['_name'])) |
| | | { |
| | | $name = trim(get_input_value('_name', RCUBE_INPUT_POST, FALSE, 'UTF-7')); |
| | | $name = trim(get_input_value('_name', RCUBE_INPUT_POST, FALSE, 'UTF7-IMAP')); |
| | | $create = $IMAP->create_mailbox($name, TRUE); |
| | | } |
| | | |
| | |
| | | $delimiter = $IMAP->get_hierarchy_delimiter(); |
| | | $folderlist = $IMAP->list_unsubscribed(); |
| | | $index = array_search($create, $folderlist); |
| | | $before = $index !== false && isset($folderlist[$index+1]) ? rcube_charset_convert($folderlist[$index+1], 'UTF-7') : false; |
| | | $before = $index !== false && isset($folderlist[$index+1]) ? rcube_charset_convert($folderlist[$index+1], 'UTF7-IMAP') : false; |
| | | |
| | | $create = rcube_charset_convert($create, 'UTF-7'); |
| | | $create = rcube_charset_convert($create, 'UTF7-IMAP'); |
| | | $foldersplit = explode($delimiter, $create); |
| | | $display_create = str_repeat(' ', substr_count($create, $delimiter)) . $foldersplit[count($foldersplit)-1]; |
| | | |
| | |
| | | { |
| | | $name_utf8 = trim(get_input_value('_folder_newname', RCUBE_INPUT_POST)); |
| | | $oldname_utf8 = get_input_value('_folder_oldname', RCUBE_INPUT_POST); |
| | | $name = rcube_charset_convert($name_utf8, 'UTF-8', 'UTF-7'); |
| | | $oldname = rcube_charset_convert($oldname_utf8, 'UTF-8', 'UTF-7'); |
| | | $name = rcube_charset_convert($name_utf8, RCMAIL_CHARSET, 'UTF7-IMAP'); |
| | | $oldname = rcube_charset_convert($oldname_utf8, RCMAIL_CHARSET, 'UTF7-IMAP'); |
| | | |
| | | $rename = $IMAP->rename_mailbox($oldname, $name); |
| | | } |
| | |
| | | $foldersplit = explode($delimiter, $folderlist[$x]); |
| | | $level = count($foldersplit) - 1; |
| | | $display_rename = str_repeat(' ', $level) |
| | | . rcube_charset_convert($foldersplit[$level], 'UTF-7'); |
| | | . rcube_charset_convert($foldersplit[$level], 'UTF7-IMAP'); |
| | | |
| | | $before = isset($folderlist[$x+1]) ? rcube_charset_convert($folderlist[$x+1], 'UTF-7') : false; |
| | | $before = isset($folderlist[$x+1]) ? rcube_charset_convert($folderlist[$x+1], 'UTF7-IMAP') : false; |
| | | |
| | | $OUTPUT->command('replace_folder_row', rcube_charset_convert($oldfolder, 'UTF-7'), |
| | | rcube_charset_convert($folderlist[$x], 'UTF-7'), $display_rename, $before); |
| | | $OUTPUT->command('replace_folder_row', rcube_charset_convert($oldfolder, 'UTF7-IMAP'), |
| | | rcube_charset_convert($folderlist[$x], 'UTF7-IMAP'), $display_rename, $before); |
| | | } |
| | | } |
| | | |
| | | $foldersplit = explode($delimiter, $rename); |
| | | $level = count($foldersplit) - 1; |
| | | $display_rename = str_repeat(' ', $level) . rcube_charset_convert($foldersplit[$level], 'UTF-7'); |
| | | $display_rename = str_repeat(' ', $level) . rcube_charset_convert($foldersplit[$level], 'UTF7-IMAP'); |
| | | $index = array_search($rename, $folderlist); |
| | | $before = $index !== false && isset($folderlist[$index+1]) ? rcube_charset_convert($folderlist[$index+1], 'UTF-7') : false; |
| | | $before = $index !== false && isset($folderlist[$index+1]) ? rcube_charset_convert($folderlist[$index+1], 'UTF7-IMAP') : false; |
| | | |
| | | $OUTPUT->command('replace_folder_row', $oldname_utf8, rcube_charset_convert($rename, 'UTF-7'), $display_rename, $before); |
| | | |
| | | $OUTPUT->command('replace_folder_row', $oldname_utf8, rcube_charset_convert($rename, 'UTF7-IMAP'), $display_rename, $before); |
| | | $OUTPUT->command('reset_folder_rename'); |
| | | } |
| | | else if (!$rename && $OUTPUT->ajax_call) |
| | |
| | | $delimiter = $IMAP->get_hierarchy_delimiter(); |
| | | |
| | | $mboxes_utf8 = get_input_value('_mboxes', RCUBE_INPUT_POST); |
| | | $mboxes = rcube_charset_convert($mboxes_utf8, 'UTF-8', 'UTF-7'); |
| | | $mboxes = rcube_charset_convert($mboxes_utf8, RCMAIL_CHARSET, 'UTF7-IMAP'); |
| | | |
| | | if ($mboxes) |
| | | $deleted = $IMAP->delete_mailbox(array($mboxes)); |
| | |
| | | { |
| | | if (preg_match('/^'. preg_quote($mboxes.$delimiter, '/') .'/', $mbox)) |
| | | { |
| | | $OUTPUT->command('remove_folder_row', rcube_charset_convert($mbox, 'UTF-7')); |
| | | $OUTPUT->command('remove_folder_row', rcube_charset_convert($mbox, 'UTF7-IMAP')); |
| | | } |
| | | } |
| | | $OUTPUT->show_message('folderdeleted', 'confirmation'); |
| | |
| | | // pre-process folders list |
| | | foreach ($a_unsubscribed as $i => $folder) { |
| | | $foldersplit = explode($delimiter, $folder); |
| | | $name = rcube_charset_convert(array_pop($foldersplit), 'UTF-7'); |
| | | $name = rcube_charset_convert(array_pop($foldersplit), 'UTF7-IMAP'); |
| | | $parent_folder = join($delimiter, $foldersplit); |
| | | $level = count($foldersplit); |
| | | |
| | |
| | | for ($i=1; $i<=$level; $i++) { |
| | | $ancestor_folder = join($delimiter, array_slice($foldersplit, 0, $i)); |
| | | if ($ancestor_folder && !$seen[$ancestor_folder]++) { |
| | | $ancestor_name = rcube_charset_convert($foldersplit[$i-1], 'UTF-7'); |
| | | $ancestor_name = rcube_charset_convert($foldersplit[$i-1], 'UTF7-IMAP'); |
| | | $list_folders[] = array('id' => $ancestor_folder, 'name' => $ancestor_name, 'level' => $i-1, 'virtual' => true); |
| | | } |
| | | } |
| | |
| | | $classes = array($i%2 ? 'even' : 'odd'); |
| | | $folder_js = JQ($folder['id']); |
| | | $display_folder = str_repeat(' ', $folder['level']) . ($protected ? rcmail_localize_foldername($folder['id']) : $folder['name']); |
| | | $folder_utf8 = rcube_charset_convert($folder['id'], 'UTF-7'); |
| | | $folder_utf8 = rcube_charset_convert($folder['id'], 'UTF7-IMAP'); |
| | | |
| | | if ($folder['virtual']) |
| | | $classes[] = 'virtual'; |