diff options
Diffstat (limited to 'program/include')
| -rw-r--r-- | program/include/main.inc | 164 | ||||
| -rw-r--r-- | program/include/rcube_config.php | 4 | ||||
| -rw-r--r-- | program/include/rcube_imap.php | 2 | 
3 files changed, 134 insertions, 36 deletions
diff --git a/program/include/main.inc b/program/include/main.inc index f111ac9a6..7a0f0ca16 100644 --- a/program/include/main.inc +++ b/program/include/main.inc @@ -205,7 +205,6 @@ function rcube_charset_convert($str, $from, $to=NULL)    // convert charset using mbstring module    if ($mbstring_loaded) { -    $aliases['UTF-7'] = 'UTF7-IMAP';      $aliases['WINDOWS-1257'] = 'ISO-8859-13';      if (is_null($mbstring_list)) { @@ -220,9 +219,6 @@ function rcube_charset_convert($str, $from, $to=NULL)      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;      }    } @@ -231,35 +227,49 @@ function rcube_charset_convert($str, $from, $to=NULL)      $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 @@ -304,6 +314,7 @@ function rcube_parse_charset($charset)      'ISO88598I'     => 'ISO-8859-8',      'KSC56011987'   => 'EUC-KR',      'UNICODE'	    => 'UTF-8', +    'UTF7IMAP'	    => 'UTF7-IMAP'    );    $str = preg_replace('/[^a-z0-9]/i', '', $charset); @@ -322,6 +333,93 @@ function rcube_parse_charset($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; +} + + +/**   * Replacing specials characters to a specific encoding type   *   * @param  string  Input string @@ -408,7 +506,7 @@ function rep_specialchars_output($str, $enctype='', $mode='', $newlines=TRUE)    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));      } @@ -1057,7 +1155,7 @@ function rcmail_build_folder_tree(&$arrFolders, $folder, $delm='/', $path='')    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());    } @@ -1232,7 +1330,7 @@ function rcmail_localize_foldername($name)    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');  } diff --git a/program/include/rcube_config.php b/program/include/rcube_config.php index 60064e7f5..56f577bda 100644 --- a/program/include/rcube_config.php +++ b/program/include/rcube_config.php @@ -78,11 +78,11 @@ class rcube_config      // 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) { diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php index 67be40346..ca3551cb2 100644 --- a/program/include/rcube_imap.php +++ b/program/include/rcube_imap.php @@ -2762,7 +2762,7 @@ class rcube_imap        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  | 
