thomascube
2009-07-13 afc6e4bd108525104b61a46f9973f8f8358c6dd2
program/include/main.inc
@@ -128,7 +128,9 @@
 */
function rcmail_temp_gc()
  {
  $tmp = unslashify($CONFIG['temp_dir']);
  $rcmail = rcmail::get_instance();
  $tmp = unslashify($rcmail->config->get('temp_dir'));
  $expire = mktime() - 172800;  // expire in 48 hours
  if ($dir = opendir($tmp))
@@ -181,20 +183,19 @@
  static $mbstring_loaded = null;
  static $mbstring_list = null;
  static $convert_warning = false;
  static $conv = null;
  $error = false;
  $conv = null;
  $to = empty($to) ? $to = strtoupper(RCMAIL_CHARSET) : rcube_parse_charset($to);
  $from = rcube_parse_charset($from);
  if ($from == $to || empty($str) || empty($from))
    return $str;
  // convert charset using iconv module  
  if (function_exists('iconv') && $from != 'UTF-7' && $to != 'UTF-7') {
    $aliases['GB2312'] = 'GB18030';
    $_iconv = iconv(($aliases[$from] ? $aliases[$from] : $from), ($aliases[$to] ? $aliases[$to] : $to) . "//IGNORE", $str);
    $_iconv = iconv($from, $to . '//IGNORE', $str);
    if ($_iconv !== false) {
        return $_iconv;
    }
@@ -222,33 +223,29 @@
    }
  }
  # try to convert with custom classes
  if (class_exists('utf8'))
    $conv = new utf8();
  // convert string to UTF-8
  // convert charset using bundled classes/functions
  if ($to == 'UTF-8') {
    if ($from == 'UTF7-IMAP') {
      if ($_str = utf7_to_utf8($str))
        $str = $_str;
      else
        $error = true;
        return $_str;
    }
    else if ($from == 'UTF-7') {
      if ($_str = rcube_utf7_to_utf8($str))
        $str = $_str;
      else
        $error = true;
        return $_str;
    }
    else if (($from == 'ISO-8859-1') && function_exists('utf8_encode')) {
      $str = utf8_encode($str);
      return utf8_encode($str);
    }
    else if ($from != 'UTF-8' && $conv) {
      $conv->loadCharset($from);
      $str = $conv->strToUtf8($str);
    else if (class_exists('utf8')) {
      if (!$conv)
        $conv = new utf8($from);
      else
        $conv->loadCharset($from);
      if($_str = $conv->strToUtf8($str))
        return $_str;
    }
    else if ($from != 'UTF-8')
      $error = true;
    $error = true;
  }
  
  // encode string for output
@@ -256,35 +253,37 @@
    // @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;
        return $_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 (class_exists('utf8')) {
      if (!$conv)
        $conv = new utf8($to);
      else
        $conv->loadCharset($from);
      if ($_str = $conv->strToUtf8($str))
        return $_str;
    }
    else if ($to != 'UTF-8') {
      $error = true;
    }
    $error = true;
  }
  
  // report error
  if ($error && !$convert_warning){
  if ($error && !$convert_warning) {
    raise_error(array(
      'code' => 500,
      'type' => 'php',
      'file' => __FILE__,
      'line' => __LINE__,
      'message' => "Could not convert string from $from to $to. Make sure iconv/mbstring is installed or lib/utf8.class is available."
      ), true, false);
    
    $convert_warning = true;
  }
  
  // return UTF-8 string
  // return UTF-8 or original string
  return $str;
  }
@@ -304,17 +303,23 @@
  # RFC1642
  $charset = str_replace('UNICODE-1-1-', '', $charset);
  # Aliases: some of them from HTML5 spec.
  $aliases = array(
    'USASCII'       => 'ISO-8859-1',
    'ANSIX31101983' => 'ISO-8859-1',
    'ANSIX341968'   => 'ISO-8859-1',
    'USASCII'       => 'WINDOWS-1252',
    'ANSIX31101983' => 'WINDOWS-1252',
    'ANSIX341968'   => 'WINDOWS-1252',
    'UNKNOWN8BIT'   => 'ISO-8859-15',
    'XUNKNOWN'      => 'ISO-8859-15',
    'XUSERDEFINED'  => 'ISO-8859-15',
    'ISO88598I'     => 'ISO-8859-8',
    'KSC56011987'   => 'EUC-KR',
    'GB2312'        => 'GBK',
    'GB231280'       => 'GBK',
    'UNICODE'       => 'UTF-8',
    'UTF7IMAP'       => 'UTF7-IMAP'
    'UTF7IMAP'       => 'UTF7-IMAP',
    'XXBIG5'       => 'BIG5',
    'TIS620'       => 'WINDOWS-874',
    'ISO88599'       => 'WINDOWS-1254',
    'ISO885911'       => 'WINDOWS-874',
  );
  $str = preg_replace('/[^a-z0-9]/i', '', $charset);
@@ -325,8 +330,12 @@
  if (preg_match('/UTF(7|8|16|32)(BE|LE)*/', $str, $m))
    return 'UTF-' . $m[1] . $m[2];
  if (preg_match('/ISO8859([0-9]{0,2})/', $str, $m))
    return 'ISO-8859-' . ($m[1] ? $m[1] : 1);
  if (preg_match('/ISO8859([0-9]{0,2})/', $str, $m)) {
    $iso = 'ISO-8859-' . ($m[1] ? $m[1] : 1);
    # some clients sends windows-1252 text as latin1,
    # it is safe to use windows-1252 for all latin1
    return $iso == 'ISO-8859-1' ? 'WINDOWS-1252' : $iso;
    }
  return $charset;
  }
@@ -434,17 +443,8 @@
  static $js_rep_table = false;
  static $xml_rep_table = false;
  $charset = rcmail::get_instance()->config->get('charset', RCMAIL_CHARSET);
  $is_iso_8859_1 = false;
  if ($charset == 'ISO-8859-1') {
    $is_iso_8859_1 = true;
  }
  if (!$enctype)
    $enctype = $OUTPUT->type;
  // encode for plaintext
  if ($enctype=='text')
    return str_replace("\r\n", "\n", $mode=='remove' ? strip_tags($str) : $str);
  // encode for HTML output
  if ($enctype=='html')
@@ -475,9 +475,6 @@
    return $newlines ? nl2br($out) : $out;
    }
  if ($enctype=='url')
    return rawurlencode($str);
  // if the replace tables for XML and JS are not yet defined
  if ($js_rep_table===false)
    {
@@ -485,12 +482,7 @@
    $xml_rep_table['&'] = '&';
    for ($c=160; $c<256; $c++)  // can be increased to support more charsets
      {
      $xml_rep_table[Chr($c)] = "&#$c;";
      if ($is_iso_8859_1)
        $js_rep_table[Chr($c)] = sprintf("\\u%04x", $c);
      }
    $xml_rep_table['"'] = '&quot;';
    $js_rep_table['"'] = '\\"';
@@ -498,18 +490,20 @@
    $js_rep_table["\\"] = "\\\\";
    }
  // encode for javascript use
  if ($enctype=='js')
    return preg_replace(array("/\r?\n/", "/\r/", '/<\\//'), array('\n', '\n', '<\\/'), strtr($str, $js_rep_table));
  // encode for plaintext
  if ($enctype=='text')
    return str_replace("\r\n", "\n", $mode=='remove' ? strip_tags($str) : $str);
  if ($enctype=='url')
    return rawurlencode($str);
  // encode for XML
  if ($enctype=='xml')
    return strtr($str, $xml_rep_table);
  // encode for javascript use
  if ($enctype=='js')
    {
    if ($charset!='UTF-8')
      $str = rcube_charset_convert($str, RCMAIL_CHARSET, $charset);
    return preg_replace(array("/\r?\n/", "/\r/", '/<\\//'), array('\n', '\n', '<\\/'), strtr($str, $js_rep_table));
    }
  // no encoding given -> return original string
  return $str;
@@ -568,7 +562,10 @@
    else if (isset($_COOKIE[$fname]))
      $value = $_COOKIE[$fname];
    }
  if (empty($value))
    return $value;
  // strip single quotes if magic_quotes_sybase is enabled
  if (ini_get('magic_quotes_sybase'))
    $value = str_replace("''", "'", $value);
@@ -589,12 +586,12 @@
/**
 * Remove all non-ascii and non-word chars
 * except . and -
 * except ., -, _
 */
function asciiwords($str, $css_id = false)
function asciiwords($str, $css_id = false, $replace_with = '')
{
  $allowed = 'a-z0-9\_\-' . (!$css_id ? '\.' : '');
  return preg_replace("/[^$allowed]/i", '', $str);
  return preg_replace("/[^$allowed]/i", $replace_with, $str);
}
/**
@@ -727,7 +724,7 @@
  $replacements = new rcube_string_replacer;
  
  // ignore the whole block if evil styles are detected
  $stripped = preg_replace('/[^a-z\(:]/', '', rcmail_xss_entitiy_decode($source));
  $stripped = preg_replace('/[^a-z\(:]/', '', rcmail_xss_entity_decode($source));
  if (preg_match('/expression|behavior|url\(|import/', $stripped))
    return '/* evil! */';
@@ -768,22 +765,22 @@
 * @param string CSS content to decode
 * @return string Decoded string
 */
function rcmail_xss_entitiy_decode($content)
function rcmail_xss_entity_decode($content)
{
  $out = html_entity_decode(html_entity_decode($content));
  $out = preg_replace_callback('/\\\([0-9a-f]{4})/i', 'rcmail_xss_entitiy_decode_callback', $out);
  $out = preg_replace_callback('/\\\([0-9a-f]{4})/i', 'rcmail_xss_entity_decode_callback', $out);
  $out = preg_replace('#/\*.*\*/#Um', '', $out);
  return $out;
}
/**
 * preg_replace_callback callback for rcmail_xss_entitiy_decode_callback
 * preg_replace_callback callback for rcmail_xss_entity_decode_callback
 *
 * @param array matches result from preg_replace_callback
 * @return string decoded entity
 */ 
function rcmail_xss_entitiy_decode_callback($matches)
function rcmail_xss_entity_decode_callback($matches)
  return chr(hexdec($matches[1]));
}
@@ -892,6 +889,9 @@
  else if (!$format)
    $format = $CONFIG['date_long'] ? $CONFIG['date_long'] : 'd.m.Y H:i';
  // strftime() format
  if (preg_match('/%[a-z]+/i', $format))
    return strftime($format, $timestamp);
  // parse format string manually in order to provide localized weekday and month names
  // an alternative would be to convert the date() format string to fit with strftime()
@@ -987,23 +987,30 @@
 */
function write_log($name, $line)
  {
  global $CONFIG;
  global $CONFIG, $RCMAIL;
  if (!is_string($line))
    $line = var_export($line, true);
 
  if (empty($CONFIG['log_date_format']))
    $CONFIG['log_date_format'] = 'd-M-Y H:i:s O';
  // trigger logging hook
  if (is_object($RCMAIL) && is_object($RCMAIL->plugins)) {
    $log = $RCMAIL->plugins->exec_hook('write_log', array('name' => $name, 'line' => $line));
    $name = $log['name'];
    $line = $log['line'];
    if ($log['abort'])
      return;
  }
 
  $log_entry = sprintf("[%s]: %s\n", date($CONFIG['log_date_format']), $line);
  if ($CONFIG['log_driver'] == 'syslog') {
    if ($name == 'errors')
      $prio = LOG_ERR;
    else
      $prio = LOG_INFO;
    $prio = $name == 'errors' ? LOG_ERR : LOG_INFO;
    syslog($prio, $log_entry);
  } else {
  }
  else {
    // log_driver == 'file' is assumed here
    if (empty($CONFIG['log_dir']))
      $CONFIG['log_dir'] = INSTALL_PATH.'logs';
@@ -1022,17 +1029,16 @@
 * @access private
 */
function rcube_timer()
  {
  list($usec, $sec) = explode(" ", microtime());
  return ((float)$usec + (float)$sec);
  }
{
  return microtime(true);
}
  
/**
 * @access private
 */
function rcube_print_time($timer, $label='Timer')
  {
function rcube_print_time($timer, $label='Timer', $dest='console')
{
  static $print_count = 0;
  
  $print_count++;
@@ -1042,8 +1048,8 @@
  if (empty($label))
    $label = 'Timer '.$print_count;
  
  console(sprintf("%s: %0.4f sec", $label, $diff));
  }
  write_log($dest, sprintf("%s: %0.4f sec", $label, $diff));
}
/**
@@ -1081,6 +1087,9 @@
    foreach ($a_folders as $folder)
      rcmail_build_folder_tree($a_mailboxes, $folder, $delimiter);
  }
  // allow plugins to alter the folder tree or to localize folder names
  $hook = $RCMAIL->plugins->exec_hook('render_mailboxlist', array('list' => $a_mailboxes, 'delimiter' => $delimiter));
  if ($type=='select') {
    $select = new html_select($attrib);
@@ -1089,12 +1098,12 @@
    if ($attrib['noselection'])
      $select->add(rcube_label($attrib['noselection']), '0');
    
    rcmail_render_folder_tree_select($a_mailboxes, $mbox_name, $attrib['maxlength'], $select, $attrib['realnames']);
    rcmail_render_folder_tree_select($hook['list'], $mbox_name, $attrib['maxlength'], $select, $attrib['realnames']);
    $out = $select->show();
  }
  else {
    $js_mailboxlist = array();
    $out = html::tag('ul', $attrib, rcmail_render_folder_tree_html($a_mailboxes, $mbox_name, $js_mailboxlist, $attrib), html::$common_attrib);
    $out = html::tag('ul', $attrib, rcmail_render_folder_tree_html($hook['list'], $mbox_name, $js_mailboxlist, $attrib), html::$common_attrib);
    
    $RCMAIL->output->add_gui_object('mailboxlist', $attrib['id']);
    $RCMAIL->output->set_env('mailboxes', $js_mailboxlist);
@@ -1201,7 +1210,7 @@
    }
    // make folder name safe for ids and class names
    $folder_id = asciiwords($folder['id'], true);
    $folder_id = asciiwords($folder['id'], true, '_');
    $classes = array('mailbox');
    // set special class for Sent, Drafts, Trash and Junk