thomascube
2011-12-16 f94e442469deca30b39f3fa08aade83cbd0ede70
program/include/main.inc
@@ -640,20 +640,23 @@
function get_input_value($fname, $source, $allow_html=FALSE, $charset=NULL)
{
  $value = NULL;
  if ($source==RCUBE_INPUT_GET && isset($_GET[$fname]))
    $value = $_GET[$fname];
  else if ($source==RCUBE_INPUT_POST && isset($_POST[$fname]))
    $value = $_POST[$fname];
  else if ($source==RCUBE_INPUT_GPC)
    {
  if ($source == RCUBE_INPUT_GET) {
    if (isset($_GET[$fname]))
      $value = $_GET[$fname];
  }
  else if ($source == RCUBE_INPUT_POST) {
    if (isset($_POST[$fname]))
      $value = $_POST[$fname];
  }
  else if ($source == RCUBE_INPUT_GPC) {
    if (isset($_POST[$fname]))
      $value = $_POST[$fname];
    else if (isset($_GET[$fname]))
      $value = $_GET[$fname];
    else if (isset($_COOKIE[$fname]))
      $value = $_COOKIE[$fname];
    }
  }
  return parse_input_value($value, $allow_html, $charset);
}
@@ -661,7 +664,7 @@
/**
 * Parse/validate input value. See get_input_value()
 * Performs stripslashes() and charset conversion if necessary
 *
 *
 * @param  string   Input value
 * @param  boolean  Allow HTML tags in field value
 * @param  string   Charset to convert into
@@ -687,15 +690,21 @@
  else if (get_magic_quotes_gpc() || get_magic_quotes_runtime())
    $value = stripslashes($value);
  // remove HTML tags if not allowed
  // remove HTML tags if not allowed
  if (!$allow_html)
    $value = strip_tags($value);
  $output_charset = is_object($OUTPUT) ? $OUTPUT->get_charset() : null;
  // remove invalid characters (#1488124)
  if ($output_charset == 'UTF-8')
    $value = rc_utf8_clean($value);
  // convert to internal charset
  if (is_object($OUTPUT) && $charset)
    return rcube_charset_convert($value, $OUTPUT->get_charset(), $charset);
  else
    return $value;
  if ($charset && $output_charset)
    $value = rcube_charset_convert($value, $output_charset, $charset);
  return $value;
}
/**
@@ -711,10 +720,10 @@
  $src = $mode == RCUBE_INPUT_GET ? $_GET : ($mode == RCUBE_INPUT_POST ? $_POST : $_REQUEST);
  foreach ($src as $key => $value) {
    $fname = $key[0] == '_' ? substr($key, 1) : $key;
    if ($ignore && !preg_match("/($ignore)/", $fname))
    if ($ignore && !preg_match('/^(' . $ignore . ')$/', $fname))
      $out[$fname] = get_input_value($key, $mode);
  }
  return $out;
}
@@ -730,12 +739,14 @@
/**
 * Convert the given string into a valid HTML identifier
 * Same functionality as done in app.js with this.identifier_expr
 *
 * Same functionality as done in app.js with rcube_webmail.html_identifier()
 */
function html_identifier($str)
function html_identifier($str, $encode=false)
{
  return asciiwords($str, true, '_');
  if ($encode)
    return rtrim(strtr(base64_encode($str), '+/', '-_'), '=');
  else
    return asciiwords($str, true, '_');
}
/**
@@ -872,23 +883,37 @@
 * @param string Container ID to use as prefix
 * @return string Modified CSS source
 */
function rcmail_mod_css_styles($source, $container_id)
function rcmail_mod_css_styles($source, $container_id, $allow_remote=false)
  {
  $last_pos = 0;
  $replacements = new rcube_string_replacer;
  // ignore the whole block if evil styles are detected
  $stripped = preg_replace('/[^a-z\(:;]/', '', rcmail_xss_entity_decode($source));
  if (preg_match('/expression|behavior|url\(|import[^a]/', $stripped))
  $source = rcmail_xss_entity_decode($source);
  $stripped = preg_replace('/[^a-z\(:;]/i', '', $source);
  $evilexpr = 'expression|behavior|javascript:|import[^a]' . (!$allow_remote ? '|url\(' : '');
  if (preg_match("/$evilexpr/i", $stripped))
    return '/* evil! */';
  // remove css comments (sometimes used for some ugly hacks)
  $source = preg_replace('!/\*(.+)\*/!Ums', '', $source);
  // cut out all contents between { and }
  while (($pos = strpos($source, '{', $last_pos)) && ($pos2 = strpos($source, '}', $pos)))
  {
    $key = $replacements->add(substr($source, $pos+1, $pos2-($pos+1)));
  while (($pos = strpos($source, '{', $last_pos)) && ($pos2 = strpos($source, '}', $pos))) {
    $styles = substr($source, $pos+1, $pos2-($pos+1));
    // check every line of a style block...
    if ($allow_remote) {
      $a_styles = preg_split('/;[\r\n]*/', $styles, -1, PREG_SPLIT_NO_EMPTY);
      foreach ($a_styles as $line) {
        $stripped = preg_replace('/[^a-z\(:;]/i', '', $line);
        // ... and only allow strict url() values
        if (stripos($stripped, 'url(') && !preg_match('!url\s*\([ "\'](https?:)//[a-z0-9/._+-]+["\' ]\)!Uims', $line)) {
          $a_styles = array('/* evil! */');
          break;
        }
      }
      $styles = join(";\n", $a_styles);
    }
    $key = $replacements->add($styles);
    $source = substr($source, 0, $pos+1) . $replacements->get_replacement($key) . substr($source, $pos2, strlen($source)-$pos2);
    $last_pos = $pos+2;
  }
@@ -926,7 +951,7 @@
{
  $out = html_entity_decode(html_entity_decode($content));
  $out = preg_replace_callback('/\\\([0-9a-f]{4})/i', 'rcmail_xss_entity_decode_callback', $out);
  $out = preg_replace('#/\*.*\*/#Um', '', $out);
  $out = preg_replace('#/\*.*\*/#Ums', '', $out);
  return $out;
}
@@ -1145,7 +1170,7 @@
  global $RCMAIL;
  static $a_mailboxes;
  $attrib += array('maxlength' => 100, 'realnames' => false);
  $attrib += array('maxlength' => 100, 'realnames' => false, 'unreadwrap' => ' (%s)');
  // add some labels to client
  $RCMAIL->output->add_label('purgefolderconfirm', 'deletemessagesconfirm');
@@ -1192,6 +1217,7 @@
    $RCMAIL->output->add_gui_object('mailboxlist', $attrib['id']);
    $RCMAIL->output->set_env('mailboxes', $js_mailboxlist);
    $RCMAIL->output->set_env('unreadwrap', $attrib['unreadwrap']);
    $RCMAIL->output->set_env('collapsed_folders', (string)$RCMAIL->config->get('collapsed_folders'));
  }
@@ -1232,7 +1258,7 @@
  if ($p['noselection'])
    $select->add($p['noselection'], '');
  rcmail_render_folder_tree_select($a_mailboxes, $mbox, $p['maxlength'], $select, $p['realnames'], 0, $p['exceptions']);
  rcmail_render_folder_tree_select($a_mailboxes, $mbox, $p['maxlength'], $select, $p['realnames'], 0, $p);
  return $select;
}
@@ -1281,11 +1307,6 @@
  $path .= $prefix.$currentFolder;
  if (!isset($arrFolders[$currentFolder])) {
    // Check \Noselect option (if options are in cache)
    if (!$virtual && ($opts = $RCMAIL->imap->mailbox_options($path))) {
      $virtual = in_array('\\Noselect', $opts);
    }
    $arrFolders[$currentFolder] = array(
      'id' => $path,
      'name' => rcube_charset_convert($currentFolder, 'UTF7-IMAP'),
@@ -1313,12 +1334,14 @@
  $realnames = (bool)$attrib['realnames'];
  $msgcounts = $RCMAIL->imap->get_cache('messagecount');
  $idx = 0;
  $out = '';
  foreach ($arrFolders as $key => $folder) {
    $title = null;
    $title        = null;
    $folder_class = rcmail_folder_classname($folder['id']);
    $collapsed    = strpos($CONFIG['collapsed_folders'], '&'.rawurlencode($folder['id']).'&') !== false;
    $unread       = $msgcounts ? intval($msgcounts[$folder['id']]['UNSEEN']) : 0;
    if (($folder_class = rcmail_folder_classname($folder['id'])) && !$realnames) {
    if ($folder_class && !$realnames) {
      $foldername = rcube_label($folder_class);
    }
    else {
@@ -1334,28 +1357,15 @@
    }
    // make folder name safe for ids and class names
    $folder_id = html_identifier($folder['id']);
    $folder_id = html_identifier($folder['id'], true);
    $classes = array('mailbox');
    // set special class for Sent, Drafts, Trash and Junk
    if ($folder['id'] == $CONFIG['sent_mbox'])
      $classes[] = 'sent';
    else if ($folder['id'] == $CONFIG['drafts_mbox'])
      $classes[] = 'drafts';
    else if ($folder['id'] == $CONFIG['trash_mbox'])
      $classes[] = 'trash';
    else if ($folder['id'] == $CONFIG['junk_mbox'])
      $classes[] = 'junk';
    else if ($folder['id'] == 'INBOX')
      $classes[] = 'inbox';
    else
      $classes[] = '_'.asciiwords($folder_class ? $folder_class : strtolower($folder['id']), true);
    if ($folder_class)
      $classes[] = $folder_class;
    if ($folder['id'] == $mbox_name)
      $classes[] = 'selected';
    $collapsed = strpos($CONFIG['collapsed_folders'], '&'.rawurlencode($folder['id']).'&') !== false;
    $unread = $msgcounts ? intval($msgcounts[$folder['id']]['UNSEEN']) : 0;
    if ($folder['virtual'])
      $classes[] = 'virtual';
@@ -1363,7 +1373,7 @@
      $classes[] = 'unread';
    $js_name = JQ($folder['id']);
    $html_name = Q($foldername) . ($unread ? html::span('unreadcount', " ($unread)") : '');
    $html_name = Q($foldername) . ($unread ? html::span('unreadcount', sprintf($attrib['unreadwrap'], $unread)) : '');
    $link_attrib = $folder['virtual'] ? array() : array(
      'href' => rcmail_url('', array('_mbox' => $folder['id'])),
      'onclick' => sprintf("return %s.command('list','%s',this)", JS_OBJECT_NAME, $js_name),
@@ -1390,7 +1400,6 @@
    }
    $out .= "</li>\n";
    $idx++;
  }
  return $out;
@@ -1402,30 +1411,40 @@
 * @access private
 * @return string
 */
function rcmail_render_folder_tree_select(&$arrFolders, &$mbox_name, $maxlength, &$select, $realnames=false, $nestLevel=0, $exceptions=array())
function rcmail_render_folder_tree_select(&$arrFolders, &$mbox_name, $maxlength, &$select, $realnames=false, $nestLevel=0, $opts=array())
{
  global $RCMAIL;
  $out = '';
  foreach ($arrFolders as $key => $folder) {
    if (empty($exceptions) || !in_array($folder['id'], $exceptions)) {
      if (!$realnames && ($folder_class = rcmail_folder_classname($folder['id'])))
        $foldername = rcube_label($folder_class);
      else {
        $foldername = $folder['name'];
        // shorten the folder name to a given length
        if ($maxlength && $maxlength>1)
          $foldername = abbreviate_string($foldername, $maxlength);
      }
      $select->add(str_repeat('&nbsp;', $nestLevel*4) . $foldername, $folder['id']);
    }
    else if ($nestLevel)
    // skip exceptions (and its subfolders)
    if (!empty($opts['exceptions']) && in_array($folder['id'], $opts['exceptions'])) {
      continue;
    }
    // skip folders in which it isn't possible to create subfolders
    if (!empty($opts['skip_noinferiors']) && ($attrs = $RCMAIL->imap->mailbox_attributes($folder['id']))
        && in_array('\\Noinferiors', $attrs)
    ) {
      continue;
    }
    if (!$realnames && ($folder_class = rcmail_folder_classname($folder['id'])))
      $foldername = rcube_label($folder_class);
    else {
      $foldername = $folder['name'];
      // shorten the folder name to a given length
      if ($maxlength && $maxlength>1)
        $foldername = abbreviate_string($foldername, $maxlength);
    }
    $select->add(str_repeat('&nbsp;', $nestLevel*4) . $foldername, $folder['id']);
    if (!empty($folder['folders']))
      $out .= rcmail_render_folder_tree_select($folder['folders'], $mbox_name, $maxlength,
        $select, $realnames, $nestLevel+1, $exceptions);
        $select, $realnames, $nestLevel+1, $opts);
  }
  return $out;
@@ -1589,6 +1608,26 @@
/**
 * Generate CSS classes from mimetype and filename extension
 *
 * @param string Mimetype
 * @param string The filename
 * @return string CSS classes separated by space
 */
function rcmail_filetype2classname($mimetype, $filename)
{
  list($primary, $secondary) = explode('/', $mimetype);
  $classes = array($primary ? $primary : 'unknown');
  if ($secondary)
    $classes[] = $secondary;
  if (preg_match('/\.([a-z0-9]+)$/', $filename, $m))
    $classes[] = $m[1];
  return join(" ", $classes);
}
/**
 * Output HTML editor scripts
 *
 * @param string Editor mode
@@ -1596,7 +1635,7 @@
 */
function rcube_html_editor($mode='')
{
  global $RCMAIL, $CONFIG;
  global $RCMAIL;
  $hook = $RCMAIL->plugins->exec_hook('html_editor', array('mode' => $mode));
@@ -1605,8 +1644,11 @@
  $lang = strtolower($_SESSION['language']);
  // TinyMCE uses 'tw' for zh_TW (which is wrong, because tw is a code of Twi language)
  $lang = ($lang == 'zh_tw') ? 'tw' : substr($lang, 0, 2);
  // TinyMCE uses two-letter lang codes, with exception of Chinese
  if (strpos($lang, 'zh_') === 0)
    $lang = str_replace('_', '-', $lang);
  else
    $lang = substr($lang, 0, 2);
  if (!file_exists(INSTALL_PATH . 'program/js/tiny_mce/langs/'.$lang.'.js'))
    $lang = 'en';
@@ -1618,8 +1660,8 @@
        'mode'       => $mode,
        'skin_path'  => '$__skin_path',
        'lang'       => $lang,
        'spellcheck' => intval($CONFIG['enable_spellcheck']),
        'spelldict'  => intval($CONFIG['spellcheck_dictionary']),
        'spellcheck' => intval($RCMAIL->config->get('enable_spellcheck')),
        'spelldict'  => intval($RCMAIL->config->get('spellcheck_dictionary')),
    ))), 'foot');
}
@@ -1844,6 +1886,21 @@
  $date = preg_replace('/[+-][0-9]{4}$/', $tz, $date);
  return $date;
}
/**
 * Check if we can process not exceeding memory_limit
 *
 * @param integer Required amount of memory
 * @return boolean
 */
function rcmail_mem_check($need)
{
  $mem_limit = parse_bytes(ini_get('memory_limit'));
  $memory    = function_exists('memory_get_usage') ? memory_get_usage() : 16*1024*1024; // safe value: 16MB
  return $mem_limit && $memory + $need > $mem_limit ? false : true;
}
@@ -2386,3 +2443,27 @@
    $RCMAIL->output->set_env('autocomplete_min_length', $RCMAIL->config->get('autocomplete_min_length'));
    $RCMAIL->output->add_label('autocompletechars', 'autocompletemore');
}
function rcube_fontdefs($font = null)
{
  $fonts = array(
    'Andale Mono'   => '"Andale Mono",Times,monospace',
    'Arial'         => 'Arial,Helvetica,sans-serif',
    'Arial Black'   => '"Arial Black","Avant Garde",sans-serif',
    'Book Antiqua'  => '"Book Antiqua",Palatino,serif',
    'Courier New'   => '"Courier New",Courier,monospace',
    'Georgia'       => 'Georgia,Palatino,serif',
    'Helvetica'     => 'Helvetica,Arial,sans-serif',
    'Impact'        => 'Impact,Chicago,sans-serif',
    'Tahoma'        => 'Tahoma,Arial,Helvetica,sans-serif',
    'Terminal'      => 'Terminal,Monaco,monospace',
    'Times New Roman' => '"Times New Roman",Times,serif',
    'Trebuchet MS'  => '"Trebuchet MS",Geneva,sans-serif',
    'Verdana'       => 'Verdana,Geneva,sans-serif',
  );
  if ($font)
    return $fonts[$font];
  return $fonts;
}