diff options
author | alecpl <alec@alec.pl> | 2011-11-28 09:03:27 +0000 |
---|---|---|
committer | alecpl <alec@alec.pl> | 2011-11-28 09:03:27 +0000 |
commit | 77449d011b2367a9f3d7bb179534aa09865aa26e (patch) | |
tree | 20a299715c627cecdc2f7247056dde120748c6a7 /program | |
parent | 2a3e02769d2014038675a5d8ddf18d1dba87bf2f (diff) |
- Applied fixes from trunk up to r5498
Diffstat (limited to 'program')
-rw-r--r-- | program/include/main.inc | 43 | ||||
-rw-r--r-- | program/include/rcube_browser.php | 24 | ||||
-rw-r--r-- | program/include/rcube_config.php | 7 | ||||
-rw-r--r-- | program/include/rcube_smtp.php | 2 | ||||
-rw-r--r-- | program/js/app.js | 7 | ||||
-rw-r--r-- | program/lib/html2text.php | 96 | ||||
-rw-r--r-- | program/steps/addressbook/func.inc | 2 | ||||
-rw-r--r-- | program/steps/mail/search.inc | 20 |
8 files changed, 121 insertions, 80 deletions
diff --git a/program/include/main.inc b/program/include/main.inc index 25940bd67..714764959 100644 --- a/program/include/main.inc +++ b/program/include/main.inc @@ -640,20 +640,23 @@ function JQ($str) 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 @@ function get_input_value($fname, $source, $allow_html=FALSE, $charset=NULL) /** * 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 @@ function parse_input_value($value, $allow_html=FALSE, $charset=NULL) 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 @@ function request2param($mode = RCUBE_INPUT_GPC, $ignore = 'task|action') $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; } diff --git a/program/include/rcube_browser.php b/program/include/rcube_browser.php index c89c3897f..859f36795 100644 --- a/program/include/rcube_browser.php +++ b/program/include/rcube_browser.php @@ -33,19 +33,19 @@ class rcube_browser $HTTP_USER_AGENT = strtolower($_SERVER['HTTP_USER_AGENT']); $this->ver = 0; - $this->win = strstr($HTTP_USER_AGENT, 'win'); - $this->mac = strstr($HTTP_USER_AGENT, 'mac'); - $this->linux = strstr($HTTP_USER_AGENT, 'linux'); - $this->unix = strstr($HTTP_USER_AGENT, 'unix'); + $this->win = strpos($HTTP_USER_AGENT, 'win') != false; + $this->mac = strpos($HTTP_USER_AGENT, 'mac') != false; + $this->linux = strpos($HTTP_USER_AGENT, 'linux') != false; + $this->unix = strpos($HTTP_USER_AGENT, 'unix') != false; - $this->opera = strstr($HTTP_USER_AGENT, 'opera'); - $this->ns4 = strstr($HTTP_USER_AGENT, 'mozilla/4') && !stristr($HTTP_USER_AGENT, 'msie'); - $this->ns = ($this->ns4 || strstr($HTTP_USER_AGENT, 'netscape')); - $this->ie = !$this->opera && stristr($HTTP_USER_AGENT, 'compatible; msie'); - $this->mz = !$this->ie && strstr($HTTP_USER_AGENT, 'mozilla/5'); - $this->chrome = strstr($HTTP_USER_AGENT, 'chrome'); - $this->khtml = strstr($HTTP_USER_AGENT, 'khtml'); - $this->safari = !$this->chrome && ($this->khtml || strstr($HTTP_USER_AGENT, 'safari')); + $this->opera = strpos($HTTP_USER_AGENT, 'opera') !== false; + $this->ns4 = strpos($HTTP_USER_AGENT, 'mozilla/4') !== false && strpos($HTTP_USER_AGENT, 'msie') === false; + $this->ns = ($this->ns4 || strpos($HTTP_USER_AGENT, 'netscape') !== false); + $this->ie = !$this->opera && strpos($HTTP_USER_AGENT, 'compatible; msie') !== false; + $this->mz = !$this->ie && strpos($HTTP_USER_AGENT, 'mozilla/5') !== false; + $this->chrome = strpos($HTTP_USER_AGENT, 'chrome') !== false; + $this->khtml = strpos($HTTP_USER_AGENT, 'khtml') !== false; + $this->safari = !$this->chrome && ($this->khtml || strpos($HTTP_USER_AGENT, 'safari') !== false); if ($this->ns || $this->chrome) { $test = preg_match('/(mozilla|chrome)\/([0-9.]+)/', $HTTP_USER_AGENT, $regs); diff --git a/program/include/rcube_config.php b/program/include/rcube_config.php index 01e678150..f80f92c91 100644 --- a/program/include/rcube_config.php +++ b/program/include/rcube_config.php @@ -90,11 +90,14 @@ class rcube_config // enable display_errors in 'show' level, but not for ajax requests ini_set('display_errors', intval(empty($_REQUEST['_remote']) && ($this->prop['debug_level'] & 4))); - + // set timezone auto settings values if ($this->prop['timezone'] == 'auto') { $this->prop['dst_active'] = intval(date('I')); - $this->prop['_timezone_value'] = date('Z') / 3600 - $this->prop['dst_active']; + $this->prop['_timezone_value'] = date('Z') / 3600 - $this->prop['dst_active']; + } + else if ($this->prop['dst_active'] === null) { + $this->prop['dst_active'] = intval(date('I')); } // export config data diff --git a/program/include/rcube_smtp.php b/program/include/rcube_smtp.php index 5c2dd92d2..56b601290 100644 --- a/program/include/rcube_smtp.php +++ b/program/include/rcube_smtp.php @@ -381,7 +381,7 @@ class rcube_smtp $from = $addresses[0]; // Reject envelope From: addresses with spaces. - if (strstr($from, ' ')) + if (strpos($from, ' ') !== false) return false; $lines[] = $key . ': ' . $value; diff --git a/program/js/app.js b/program/js/app.js index 6c0d2cd8d..8ffcf93af 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -5743,10 +5743,13 @@ function rcube_webmail() }); }; - this.plain2html = function(plainText, id) + this.plain2html = function(plain, id) { var lock = this.set_busy(true, 'converting'); - $('#'+id).val(plainText ? '<pre>'+plainText+'</pre>' : ''); + + plain = plain.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>'); + $('#'+id).val(plain ? '<pre>'+plain+'</pre>' : ''); + this.set_busy(false, null, lock); }; diff --git a/program/lib/html2text.php b/program/lib/html2text.php index 1ab16055b..9fc96eac7 100644 --- a/program/lib/html2text.php +++ b/program/lib/html2text.php @@ -145,7 +145,6 @@ class html2text var $search = array( "/\r/", // Non-legal carriage return "/[\n\t]+/", // Newlines and tabs - '/[ ]{2,}/', // Runs of spaces, pre-handling '/<script[^>]*>.*?<\/script>/i', // <script>s -- which strip_tags supposedly has problems with '/<style[^>]*>.*?<\/style>/i', // <style>s -- which strip_tags supposedly has problems with '/<p[^>]*>/i', // <P> @@ -161,22 +160,6 @@ class html2text '/(<table[^>]*>|<\/table>)/i', // <table> and </table> '/(<tr[^>]*>|<\/tr>)/i', // <tr> and </tr> '/<td[^>]*>(.*?)<\/td>/i', // <td> and </td> - '/&(nbsp|#160);/i', // Non-breaking space - '/&(quot|rdquo|ldquo|#8220|#8221|#147|#148);/i', - // Double quotes - '/&(apos|rsquo|lsquo|#8216|#8217);/i', // Single quotes - '/>/i', // Greater-than - '/</i', // Less-than - '/&(copy|#169);/i', // Copyright - '/&(trade|#8482|#153);/i', // Trademark - '/&(reg|#174);/i', // Registered - '/&(mdash|#151|#8212);/i', // mdash - '/&(ndash|minus|#8211|#8722);/i', // ndash - '/&(bull|#149|#8226);/i', // Bullet - '/&(pound|#163);/i', // Pound sign - '/&(euro|#8364);/i', // Euro sign - '/&(amp|#38);/i', // Ampersand: see _converter() - '/[ ]{2,}/' // Runs of spaces, post-handling ); /** @@ -189,7 +172,6 @@ class html2text var $replace = array( '', // Non-legal carriage return ' ', // Newlines and tabs - ' ', // Runs of spaces, pre-handling '', // <script>s -- which strip_tags supposedly has problems with '', // <style>s -- which strip_tags supposedly has problems with "\n\n", // <P> @@ -205,6 +187,43 @@ class html2text "\n\n", // <table> and </table> "\n", // <tr> and </tr> "\t\t\\1\n", // <td> and </td> + ); + + /** + * List of preg* regular expression patterns to search for, + * used in conjunction with $ent_replace. + * + * @var array $ent_search + * @access public + * @see $ent_replace + */ + var $ent_search = array( + '/&(nbsp|#160);/i', // Non-breaking space + '/&(quot|rdquo|ldquo|#8220|#8221|#147|#148);/i', + // Double quotes + '/&(apos|rsquo|lsquo|#8216|#8217);/i', // Single quotes + '/>/i', // Greater-than + '/</i', // Less-than + '/&(copy|#169);/i', // Copyright + '/&(trade|#8482|#153);/i', // Trademark + '/&(reg|#174);/i', // Registered + '/&(mdash|#151|#8212);/i', // mdash + '/&(ndash|minus|#8211|#8722);/i', // ndash + '/&(bull|#149|#8226);/i', // Bullet + '/&(pound|#163);/i', // Pound sign + '/&(euro|#8364);/i', // Euro sign + '/&(amp|#38);/i', // Ampersand: see _converter() + '/[ ]{2,}/', // Runs of spaces, post-handling + ); + + /** + * List of pattern replacements corresponding to patterns searched. + * + * @var array $ent_replace + * @access public + * @see $ent_search + */ + var $ent_replace = array( ' ', // Non-breaking space '"', // Double quotes "'", // Single quotes @@ -219,7 +238,7 @@ class html2text '£', 'EUR', // Euro sign. € ? '|+|amp|+|', // Ampersand: see _converter() - ' ' // Runs of spaces, post-handling + ' ', // Runs of spaces, post-handling ); /** @@ -303,7 +322,7 @@ class html2text * @see _build_link_list() */ var $_link_list = ''; - + /** * Number of valid links detected in the text, used for plain text * display (rendered similar to footnotes). @@ -314,15 +333,15 @@ class html2text */ var $_link_count = 0; - /** - * Boolean flag, true if a table of link URLs should be listed after the text. - * - * @var boolean $_do_links - * @access private - * @see html2text() + /** + * Boolean flag, true if a table of link URLs should be listed after the text. + * + * @var boolean $_do_links + * @access private + * @see html2text() */ var $_do_links = true; - + /** * Constructor. * @@ -492,15 +511,21 @@ class html2text // Convert <PRE> $this->_convert_pre($text); - // Run our defined search-and-replace + // Run our defined tags search-and-replace $text = preg_replace($this->search, $this->replace, $text); + // Run our defined tags search-and-replace with callback + $text = preg_replace_callback($this->callback_search, array('html2text', '_preg_callback'), $text); + + // Strip any other HTML tags + $text = strip_tags($text, $this->allowed_tags); + + // Run our defined entities/characters search-and-replace + $text = preg_replace($this->ent_search, $this->ent_replace, $text); + // Replace known html entities $text = html_entity_decode($text, ENT_COMPAT, 'UTF-8'); - // Run our defined search-and-replace with callback - $text = preg_replace_callback($this->callback_search, array('html2text', '_preg_callback'), $text); - // Remove unknown/unhandled entities (this cannot be done in search-and-replace block) $text = preg_replace('/&([a-zA-Z0-9]{2,6}|#[0-9]{2,4});/', '', $text); @@ -508,15 +533,12 @@ class html2text // This properly handles situation of "&quot;" in input string $text = str_replace('|+|amp|+|', '&', $text); - // Strip any other HTML tags - $text = strip_tags($text, $this->allowed_tags); - // Bring down number of empty lines to 2 max $text = preg_replace("/\n\s+\n/", "\n\n", $text); $text = preg_replace("/[\n]{3,}/", "\n\n", $text); // remove leading empty lines (can be produced by eg. P tag on the beginning) - $text = preg_replace('/^\n+/', '', $text); + $text = ltrim($text, "\n"); // Wrap the text to a readable format // for PHP versions >= 4.0.2. Default width is 75 @@ -544,9 +566,7 @@ class html2text if ( !$this->_do_links ) return $display; - if ( substr($link, 0, 7) == 'http://' || substr($link, 0, 8) == 'https://' || - substr($link, 0, 7) == 'mailto:' - ) { + if ( preg_match('!^(https?://|mailto:)!', $link) ) { $this->_link_count++; $this->_link_list .= '[' . $this->_link_count . "] $link\n"; $additional = ' [' . $this->_link_count . ']'; diff --git a/program/steps/addressbook/func.inc b/program/steps/addressbook/func.inc index 2f1fbb70f..cb5cc63dc 100644 --- a/program/steps/addressbook/func.inc +++ b/program/steps/addressbook/func.inc @@ -705,7 +705,7 @@ function rcmail_contact_photo($attrib) $RCMAIL->output->set_env('photo_placeholder', $photo_img); unset($attrib['placeholder']); - if (strpos($record['photo'], 'http:') === 0) + if (preg_match('!^https?://!i', $record['photo'])) $photo_img = $record['photo']; else if ($record['photo']) $photo_img = $RCMAIL->url(array('_action' => 'photo', '_cid' => $record['ID'], '_source' => $SOURCE_ID)); diff --git a/program/steps/mail/search.inc b/program/steps/mail/search.inc index 2e7fd130c..593eac427 100644 --- a/program/steps/mail/search.inc +++ b/program/steps/mail/search.inc @@ -31,6 +31,7 @@ $str = get_input_value('_q', RCUBE_INPUT_GET, true); $mbox = get_input_value('_mbox', RCUBE_INPUT_GET, true); $filter = get_input_value('_filter', RCUBE_INPUT_GET); $headers = get_input_value('_headers', RCUBE_INPUT_GET); +$subject = array(); $search_request = md5($mbox.$filter.$str); @@ -70,14 +71,19 @@ else if (preg_match("/^body:.*/i", $str)) list(,$srch) = explode(":", $str); $subject['text'] = "TEXT"; } -else if(trim($str)) +else if (strlen(trim($str))) { if ($headers) { - foreach(explode(',', $headers) as $header) - switch ($header) { - case 'text': $subject['text'] = 'TEXT'; break; - default: $subject[$header] = 'HEADER '.strtoupper($header); + foreach (explode(',', $headers) as $header) { + if ($header == 'text') { + // #1488208: get rid of other headers when searching by "TEXT" + $subject = array('text' => 'TEXT'); + break; } + else { + $subject[$header] = 'HEADER '.strtoupper($header); + } + } // save search modifiers for the current folder to user prefs $search_mods = $RCMAIL->config->get('search_mods', $SEARCH_MODS_DEFAULT); @@ -89,9 +95,9 @@ else if(trim($str)) } } -$search = $srch ? trim($srch) : trim($str); +$search = isset($srch) ? trim($srch) : trim($str); -if ($subject) { +if (!empty($subject)) { $search_str .= str_repeat(' OR', count($subject)-1); foreach ($subject as $sub) $search_str .= sprintf(" %s {%d}\r\n%s", $sub, strlen($search), $search); |