From e70b3b24fc8ac7b54a820ae87ce8f4af4043125e Mon Sep 17 00:00:00 2001 From: alecpl <alec@alec.pl> Date: Thu, 09 Oct 2008 02:25:43 -0400 Subject: [PATCH] - send set_unread_count() only when changing /Seen status --- program/include/main.inc | 182 ++++++++++++++++++++++++--------------------- 1 files changed, 97 insertions(+), 85 deletions(-) diff --git a/program/include/main.inc b/program/include/main.inc index 629599d..0214d32 100644 --- a/program/include/main.inc +++ b/program/include/main.inc @@ -74,17 +74,7 @@ $opt = rcmail::get_instance()->config->get($config_key); if (!empty($opt)) - { - $db = &rcmail::get_instance()->db; - - if ($db->db_provider=='pgsql') - { - $db->db_handle->setOption('disable_smart_seqname', true); - $db->db_handle->setOption('seqname_format', '%s'); - } - return $opt; - } return $sequence; } @@ -130,20 +120,6 @@ $app = rcmail::get_instance(); return $app->url((array)$p + array('_action' => $action, 'task' => $task)); } - - -/** - * Add a localized label to the client environment - * @deprecated - */ -function rcube_add_label() - { - global $OUTPUT; - - $arg_list = func_get_args(); - foreach ($arg_list as $i => $name) - $OUTPUT->add_label($name); - } /** @@ -212,6 +188,7 @@ return $str; $aliases = array( + 'US-ASCII' => 'ISO-8859-1', 'UNKNOWN-8BIT' => 'ISO-8859-15', 'X-UNKNOWN' => 'ISO-8859-15', 'X-USER-DEFINED' => 'ISO-8859-15', @@ -317,7 +294,7 @@ $is_iso_8859_1 = true; } if (!$enctype) - $enctype = $GLOBALS['OUTPUT_TYPE']; + $enctype = $OUTPUT->type; // encode for plaintext if ($enctype=='text') @@ -347,7 +324,7 @@ $str = strip_tags($str); // avoid douple quotation of & - $out = preg_replace('/&([a-z]{2,5}|#[0-9]{2,4});/', '&\\1;', strtr($str, $encode_arr)); + $out = preg_replace('/&([A-Za-z]{2,6}|#[0-9]{2,4});/', '&\\1;', strtr($str, $encode_arr)); return $newlines ? nl2br($out) : $out; } @@ -597,7 +574,8 @@ $last_pos = 0; // ignore the whole block if evil styles are detected - if (stristr($source, 'expression') || stristr($source, 'behavior')) + $stripped = preg_replace('/[^a-z\(:]/', '', rcmail_xss_entitiy_decode($source)); + if (preg_match('/expression|behavior|url\(|import/', $stripped)) return ''; // cut out all contents between { and } @@ -630,6 +608,22 @@ return $styles; } + + +/** + * Decode escaped entities used by known XSS exploits. + * See http://downloads.securityfocus.com/vulnerabilities/exploits/26800.eml for examples + * + * @param string CSS content to decode + * @return string Decoded string + */ +function rcmail_xss_entitiy_decode($content) +{ + $out = html_entity_decode(html_entity_decode($content)); + $out = preg_replace('/\\\([0-9a-f]{4})/ie', "chr(hexdec('\\1'))", $out); + $out = preg_replace('#/\*.*\*/#Um', '', $out); + return $out; +} /** @@ -706,9 +700,13 @@ return ''; // get user's timezone - $tz = $CONFIG['timezone']; - if ($CONFIG['dst_active']) - $tz++; + if ($CONFIG['timezone'] === 'auto') + $tz = isset($_SESSION['timezone']) ? $_SESSION['timezone'] : date('Z')/3600; + else { + $tz = $CONFIG['timezone']; + if ($CONFIG['dst_active']) + $tz++; + } // convert time to user's timezone $timestamp = $ts - date('Z', $ts) + ($tz * 3600); @@ -792,19 +790,20 @@ * * @param mixed Debug message or data */ -function console($msg) +function console() { - if (!is_string($msg)) - $msg = var_export($msg, true); + $msg = array(); + foreach (func_get_args() as $arg) + $msg[] = !is_string($arg) ? var_export($arg, true) : $arg; if (!($GLOBALS['CONFIG']['debug_level'] & 4)) - write_log('console', $msg); + write_log('console', join(";\n", $msg)); else if ($GLOBALS['OUTPUT']->ajax_call) - print "/*\n $msg \n*/\n"; + print "/*\n " . join(";\n", $msg) . " \n*/\n"; else { print '<div style="background:#eee; border:1px solid #ccc; margin-bottom:3px; padding:6px"><pre>'; - print $msg; + print join(";<br/>\n", $msg); print "</pre></div>\n"; } } @@ -884,14 +883,13 @@ */ function rcmail_mailbox_list($attrib) { - global $IMAP, $OUTPUT; + global $RCMAIL; static $a_mailboxes; $attrib += array('maxlength' => 100, 'relanames' => false); // add some labels to client - rcube_add_label('purgefolderconfirm'); - rcube_add_label('deletemessagesconfirm'); + $RCMAIL->output->add_label('purgefolderconfirm', 'deletemessagesconfirm'); $type = $attrib['type'] ? $attrib['type'] : 'ul'; unset($attrib['type']); @@ -900,13 +898,13 @@ $attrib['id'] = 'rcmboxlist'; // get mailbox list - $mbox_name = $IMAP->get_mailbox_name(); + $mbox_name = $RCMAIL->imap->get_mailbox_name(); // build the folders tree if (empty($a_mailboxes)) { // get mailbox list - $a_folders = $IMAP->list_mailboxes(); - $delimiter = $IMAP->get_hierarchy_delimiter(); + $a_folders = $RCMAIL->imap->list_mailboxes(); + $delimiter = $RCMAIL->imap->get_hierarchy_delimiter(); $a_mailboxes = array(); foreach ($a_folders as $folder) @@ -924,11 +922,13 @@ $out = $select->show(); } else { - $out = html::tag('ul', $attrib, rcmail_render_folder_tree_html($a_mailboxes, $mbox_name, $attrib['maxlength'], $attrib['realnames']), html::$common_attrib); + $js_mailboxlist = array(); + $out = html::tag('ul', $attrib, rcmail_render_folder_tree_html($a_mailboxes, $mbox_name, $js_mailboxlist, $attrib), html::$common_attrib); + + $RCMAIL->output->add_gui_object('mailboxlist', $attrib['id']); + $RCMAIL->output->set_env('mailboxes', $js_mailboxlist); + $RCMAIL->output->set_env('collapsed_folders', $RCMAIL->config->get('collapsed_folders')); } - - if ($type=='ul') - $OUTPUT->add_gui_object('mailboxlist', $attrib['id']); return $out; } @@ -966,64 +966,68 @@ * @access private */ function rcmail_build_folder_tree(&$arrFolders, $folder, $delm='/', $path='') - { +{ $pos = strpos($folder, $delm); - if ($pos !== false) - { + if ($pos !== false) { $subFolders = substr($folder, $pos+1); $currentFolder = substr($folder, 0, $pos); - } - else - { + $virtual = !isset($arrFolders[$currentFolder]); + } + else { $subFolders = false; $currentFolder = $folder; - } + $virtual = false; + } $path .= $currentFolder; - if (!isset($arrFolders[$currentFolder])) - { + if (!isset($arrFolders[$currentFolder])) { $arrFolders[$currentFolder] = array( 'id' => $path, 'name' => rcube_charset_convert($currentFolder, 'UTF-7'), + 'virtual' => $virtual, 'folders' => array()); - } + } + else + $arrFolders[$currentFolder]['virtual'] = $virtual; if (!empty($subFolders)) rcmail_build_folder_tree($arrFolders[$currentFolder]['folders'], $subFolders, $delm, $path.$delm); - } +} /** * Return html for a structured list <ul> for the mailbox tree * @access private */ -function rcmail_render_folder_tree_html(&$arrFolders, &$mbox_name, $maxlength, $realnames=false, $nestLevel=0) - { - global $COMM_PATH, $IMAP, $CONFIG, $OUTPUT, $RCMAIL; +function rcmail_render_folder_tree_html(&$arrFolders, &$mbox_name, &$jslist, $attrib, $nestLevel=0) +{ + global $RCMAIL, $CONFIG; + + $maxlength = intval($attrib['maxlength']); + $realnames = (bool)$attrib['realnames']; + $msgcounts = $RCMAIL->imap->get_cache('messagecount'); $idx = 0; $out = ''; - foreach ($arrFolders as $key => $folder) - { + foreach ($arrFolders as $key => $folder) { $zebra_class = (($nestLevel+1)*$idx) % 2 == 0 ? 'even' : 'odd'; $title = null; - if (($folder_class = rcmail_folder_classname($folder['id'])) && !$realnames) + if (($folder_class = rcmail_folder_classname($folder['id'])) && !$realnames) { $foldername = rcube_label($folder_class); - else - { + } + else { $foldername = $folder['name']; // shorten the folder name to a given length - if ($maxlength && $maxlength>1) - { + if ($maxlength && $maxlength > 1) { $fname = abbreviate_string($foldername, $maxlength); if ($fname != $foldername) $title = $foldername; $foldername = $fname; - } } + } // make folder name safe for ids and class names $folder_id = asciiwords($folder['id'], true); @@ -1038,8 +1042,10 @@ $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); + $classes[] = '_'.asciiwords($folder_class ? $folder_class : strtolower($folder['id']), true); $classes[] = $zebra_class; @@ -1047,37 +1053,45 @@ $classes[] = 'selected'; $collapsed = preg_match('/&'.rawurlencode($folder['id']).'&/', $RCMAIL->config->get('collapsed_folders')); + $unread = $msgcounts ? intval($msgcounts[$folder['id']]['UNSEEN']) : 0; + + if ($folder['virtual']) + $classes[] = 'virtual'; + else if ($unread) + $classes[] = 'unread'; $js_name = JQ($folder['id']); + $html_name = Q($foldername . ($unread ? " ($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), + 'title' => $title, + ); + $out .= html::tag('li', array( 'id' => "rcmli".$folder_id, 'class' => join(' ', $classes), 'noclose' => true), - html::a(array( - 'href' => rcmail_url('', array('_mbox' => $folder['id'])), - 'onclick' => sprintf("return %s.command('list','%s',this)", JS_OBJECT_NAME, $js_name), - 'onmouseover' => sprintf("return %s.focus_folder('%s')", JS_OBJECT_NAME, $js_name), - 'onmouseout' => sprintf("return %s.unfocus_folder('%s')", JS_OBJECT_NAME, $js_name), - 'onmouseup' => sprintf("return %s.folder_mouse_up('%s')", JS_OBJECT_NAME, $js_name), - 'title' => $title, - ), Q($foldername)) . + html::a($link_attrib, $html_name) . (!empty($folder['folders']) ? html::div(array( 'class' => ($collapsed ? 'collapsed' : 'expanded'), 'style' => "position:absolute", 'onclick' => sprintf("%s.command('collapse-folder', '%s')", JS_OBJECT_NAME, $js_name) ), ' ') : '')); - if (!empty($folder['folders'])) - $out .= "\n<ul" . ($collapsed ? " style=\"display: none;\"" : "") . ">\n" . rcmail_render_folder_tree_html($folder['folders'], $mbox_name, $maxlength, $realnames, $nestLevel+1) . "</ul>\n"; + $jslist[$folder_id] = array('id' => $folder['id'], 'name' => $foldername, 'virtual' => $folder['virtual']); + + if (!empty($folder['folders'])) { + $out .= html::tag('ul', array('style' => ($collapsed ? "display:none;" : null)), + rcmail_render_folder_tree_html($folder['folders'], $mbox_name, $jslist, $attrib, $nestLevel+1)); + } $out .= "</li>\n"; $idx++; - } - - $OUTPUT->set_env('collapsed_folders', $RCMAIL->config->get('collapsed_folders')); + } return $out; - } +} /** @@ -1086,8 +1100,6 @@ */ function rcmail_render_folder_tree_select(&$arrFolders, &$mbox_name, $maxlength, &$select, $realnames=false, $nestLevel=0) { - global $IMAP, $OUTPUT; - $idx = 0; $out = ''; foreach ($arrFolders as $key=>$folder) -- Gitblit v1.9.1