From a02cfa9b085fc875fc55f57029a8e5846771ed5e Mon Sep 17 00:00:00 2001 From: thomascube <thomas@roundcube.net> Date: Sat, 13 Aug 2011 05:10:11 -0400 Subject: [PATCH] Fix incomplete backport from trunk --- program/include/main.inc | 175 +++++++++++++++++++++++++++++++++++++++++----------------- 1 files changed, 123 insertions(+), 52 deletions(-) diff --git a/program/include/main.inc b/program/include/main.inc index a9a96a0..842b933 100644 --- a/program/include/main.inc +++ b/program/include/main.inc @@ -92,6 +92,16 @@ return rcmail::get_instance()->gettext($p, $domain); } +/** + * Global wrapper of rcmail::text_exists() + * to check whether a text label is defined + * + * @see rcmail::text_exists() + */ +function rcube_label_exists($name, $domain=null) +{ + return rcmail::get_instance()->text_exists($name, $domain); +} /** * Overwrite action variable @@ -861,8 +871,8 @@ $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/', $stripped)) + $stripped = preg_replace('/[^a-z\(:;]/', '', rcmail_xss_entity_decode($source)); + if (preg_match('/expression|behavior|url\(|import[^a]/', $stripped)) return '/* evil! */'; // remove css comments (sometimes used for some ugly hacks) @@ -975,7 +985,7 @@ * @return string Formatted date string */ function format_date($date, $format=NULL) - { +{ global $CONFIG; $ts = NULL; @@ -999,7 +1009,7 @@ if (empty($ts)) return ''; - + // get user's timezone if ($CONFIG['timezone'] === 'auto') $tz = isset($_SESSION['timezone']) ? $_SESSION['timezone'] : date('Z')/3600; @@ -1011,7 +1021,7 @@ // convert time to user's timezone $timestamp = $ts - date('Z', $ts) + ($tz * 3600); - + // get current timestamp in user's timezone $now = time(); // local time $now -= (int)date('Z'); // make GMT time @@ -1019,30 +1029,33 @@ $now_date = getdate($now); $today_limit = mktime(0, 0, 0, $now_date['mon'], $now_date['mday'], $now_date['year']); - $week_limit = mktime(0, 0, 0, $now_date['mon'], $now_date['mday']-6, $now_date['year']); + $week_limit = mktime(0, 0, 0, $now_date['mon'], $now_date['mday']-6, $now_date['year']); // define date format depending on current time if (!$format) { - if ($CONFIG['prettydate'] && $timestamp > $today_limit && $timestamp < $now) - return sprintf('%s %s', rcube_label('today'), date($CONFIG['date_today'] ? $CONFIG['date_today'] : 'H:i', $timestamp)); + if ($CONFIG['prettydate'] && $timestamp > $today_limit && $timestamp < $now) { + $format = $CONFIG['date_today'] ? $CONFIG['date_today'] : 'H:i'; + $today = true; + } else if ($CONFIG['prettydate'] && $timestamp > $week_limit && $timestamp < $now) $format = $CONFIG['date_short'] ? $CONFIG['date_short'] : 'D H:i'; else $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); + if (preg_match('/%[a-z]+/i', $format)) { + $format = strftime($format, $timestamp); + return $today ? (rcube_label('today') . ' ' . $format) : $format; + } // 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() $out = ''; - for($i=0; $i<strlen($format); $i++) - { + for($i=0; $i<strlen($format); $i++) { if ($format{$i}=='\\') // skip escape chars continue; - + // write char "as-is" if ($format{$i}==' ' || $format{$i-1}=='\\') $out .= $format{$i}; @@ -1062,10 +1075,21 @@ $out .= strftime('%x %X', $timestamp); else $out .= date($format{$i}, $timestamp); - } - - return $out; } + + if ($today) { + $label = rcube_label('today'); + // replcae $ character with "Today" label (#1486120) + if (strpos($out, '$') !== false) { + $out = preg_replace('/\$/', $label, $out, 1); + } + else { + $out = $label . ' ' . $out; + } + } + + return $out; +} /** @@ -1224,6 +1248,19 @@ /** + * Check whether the HTTP referer matches the current request + * + * @return boolean True if referer is the same host+path, false if not + */ +function rcube_check_referer() +{ + $uri = parse_url($_SERVER['REQUEST_URI']); + $referer = parse_url(rc_request_header('Referer')); + return $referer['host'] == rc_request_header('Host') && $referer['path'] == $uri['path']; +} + + +/** * @access private * @return mixed */ @@ -1262,12 +1299,12 @@ { global $RCMAIL; static $a_mailboxes; - + $attrib += array('maxlength' => 100, 'realnames' => false); // add some labels to client $RCMAIL->output->add_label('purgefolderconfirm', 'deletemessagesconfirm'); - + $type = $attrib['type'] ? $attrib['type'] : 'ul'; unset($attrib['type']); @@ -1276,7 +1313,7 @@ // get mailbox list $mbox_name = $RCMAIL->imap->get_mailbox_name(); - + // build the folders tree if (empty($a_mailboxes)) { // get mailbox list @@ -1291,20 +1328,20 @@ // 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') { + if ($type == 'select') { $select = new html_select($attrib); - + // add no-selection option if ($attrib['noselection']) - $select->add(rcube_label($attrib['noselection']), '0'); - + $select->add(rcube_label($attrib['noselection']), ''); + 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($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); $RCMAIL->output->set_env('collapsed_folders', $RCMAIL->config->get('collapsed_folders')); @@ -1323,7 +1360,7 @@ function rcmail_mailbox_select($p = array()) { global $RCMAIL; - + $p += array('maxlength' => 100, 'realnames' => false); $a_mailboxes = array(); @@ -1396,7 +1433,7 @@ if (strlen($subFolders)) rcmail_build_folder_tree($arrFolders[$currentFolder]['folders'], $subFolders, $delm, $path.$delm); } - + /** * Return html for a structured list <ul> for the mailbox tree @@ -1406,7 +1443,7 @@ 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'); @@ -1449,15 +1486,15 @@ $classes[] = 'inbox'; else $classes[] = '_'.asciiwords($folder_class ? $folder_class : strtolower($folder['id']), true); - + $classes[] = $zebra_class; - + if ($folder['id'] == $mbox_name) $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) @@ -1481,9 +1518,9 @@ 'style' => "position:absolute", 'onclick' => sprintf("%s.command('collapse-folder', '%s')", JS_OBJECT_NAME, $js_name) ), ' ') : '')); - + $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)); @@ -1503,32 +1540,28 @@ * @return string */ function rcmail_render_folder_tree_select(&$arrFolders, &$mbox_name, $maxlength, &$select, $realnames=false, $nestLevel=0) - { - $idx = 0; +{ $out = ''; - foreach ($arrFolders as $key=>$folder) - { + + foreach ($arrFolders as $key=>$folder) { if (!$realnames && ($folder_class = rcmail_folder_classname($folder['id']))) $foldername = rcube_label($folder_class); - else - { + 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(' ', $nestLevel*4) . $foldername, $folder['id']); if (!empty($folder['folders'])) $out .= rcmail_render_folder_tree_select($folder['folders'], $mbox_name, $maxlength, $select, $realnames, $nestLevel+1); - - $idx++; - } + } return $out; - } +} /** @@ -1669,7 +1702,7 @@ { global $RCMAIL, $CONFIG; - $hook = $RCMAIL->plugins->exec_hook('hmtl_editor', array('mode' => $mode)); + $hook = $RCMAIL->plugins->exec_hook('html_editor', array('mode' => $mode)); if ($hook['abort']) return; @@ -1709,11 +1742,11 @@ ':-(' => 'smiley-frown', ':-D' => 'smiley-laughing', ':-)' => 'smiley-smile', - ':-/' => 'smiley-undecided', - ':-X' => 'smiley-embarassed', - '0:-)' => 'smiley-innocent', + ':-S' => 'smiley-undecided', + ':-$' => 'smiley-embarassed', + 'O:-)' => 'smiley-innocent', ':-|' => 'smiley-money-mouth', - ':-0' => 'smiley-surprised', + ':-O' => 'smiley-surprised', ';-)' => 'smiley-wink', ); @@ -1771,16 +1804,17 @@ * Replaces hostname variables * * @param string $name Hostname + * @param string $host Optional IMAP hostname * @return string */ -function rcube_parse_host($name) +function rcube_parse_host($name, $host='') { // %n - host $n = preg_replace('/:\d+$/', '', $_SERVER['SERVER_NAME']); // %d - domain name without first part, e.g. %d=mail.domain.tld, %m=domain.tld $d = preg_replace('/^[^\.]+\./', '', $n); // %h - IMAP host - $h = $_SESSION['imap_host']; + $h = $_SESSION['imap_host'] ? $_SESSION['imap_host'] : $host; // %z - IMAP domain without first part, e.g. %h=imap.domain.tld, %z=domain.tld $z = preg_replace('/^[^\.]+\./', '', $h); @@ -1862,6 +1896,43 @@ return false; } +/* + * Idn_to_ascii wrapper. + * Intl/Idn modules version of this function doesn't work with e-mail address + */ +function rcube_idn_to_ascii($str) +{ + return rcube_idn_convert($str, true); +} + +/* + * Idn_to_ascii wrapper. + * Intl/Idn modules version of this function doesn't work with e-mail address + */ +function rcube_idn_to_utf8($str) +{ + return rcube_idn_convert($str, false); +} + +function rcube_idn_convert($input, $is_utf=false) +{ + if ($at = strpos($input, '@')) { + $user = substr($input, 0, $at); + $domain = substr($input, $at+1); + } + else { + $domain = $input; + } + + $domain = $is_utf ? idn_to_ascii($domain) : idn_to_utf8($domain); + + if ($domain === false) { + return ''; + } + + return $at ? $user . '@' . $domain : $domain; +} + /** * Helper class to turn relative urls into absolute ones -- Gitblit v1.9.1