CHANGELOG | ●●●●● patch | view | raw | blame | history | |
plugins/managesieve/localization/pl_PL.inc | ●●●●● patch | view | raw | blame | history | |
program/include/rcube_imap.php | ●●●●● patch | view | raw | blame | history | |
program/include/rcube_imap_generic.php | ●●●●● patch | view | raw | blame | history | |
program/include/rcube_mdb2.php | ●●●●● patch | view | raw | blame | history | |
program/include/rcube_message.php | ●●●●● patch | view | raw | blame | history | |
program/js/app.js | ●●●●● patch | view | raw | blame | history | |
program/lib/html2text.php | ●●●●● patch | view | raw | blame | history | |
program/steps/mail/func.inc | ●●●●● patch | view | raw | blame | history | |
program/steps/settings/save_prefs.inc | ●●●●● patch | view | raw | blame | history |
CHANGELOG
@@ -1,6 +1,12 @@ CHANGELOG Roundcube Webmail =========================== - Support 'abort' and 'result' response in 'preferences_save' hook, add error handling - Fix bug where some content would cause hang on html2text conversion (#1487863) - Improve space-stuffing handling in format=flowed messages (#1487861) - Fix bug where some dates would produce SQL error in MySQL (#1487856) - Added workaround for some IMAP server with broken STATUS response (#1487859) - Fix bug where default_charset was not used for text messages (#1487836) - Stateless request tokens. No keep-alive necessary on login page (#1487829) - PEAR::Net_SMTP 1.5.1 - Force names of unique constraints in PostgreSQL DDL plugins/managesieve/localization/pl_PL.inc
@@ -41,10 +41,10 @@ $labels['vacationreason'] = 'Treść (przyczyna nieobecności):'; $labels['filterset'] = 'Zbiór filtrów'; $labels['filtersetadd'] = 'Dodaj zbiór filtrów'; $labels['filtersetdel'] = 'Usuń bierzący zbiór filtrów'; $labels['filtersetact'] = 'Aktywuj bierzący zbiór filtrów'; $labels['filtersetdeact'] = 'Deaktywuj bierzący zbiór filtrów'; $labels['filtersetget'] = 'Pobierz bierzący zbiór filtrów w formacie tekstowym'; $labels['filtersetdel'] = 'Usuń bieżący zbiór filtrów'; $labels['filtersetact'] = 'Aktywuj bieżący zbiór filtrów'; $labels['filtersetdeact'] = 'Deaktywuj bieżący zbiór filtrów'; $labels['filtersetget'] = 'Pobierz bieżący zbiór filtrów w formacie tekstowym'; $labels['filterdef'] = 'Definicja filtra'; $labels['filtersetname'] = 'Nazwa zbioru'; $labels['newfilterset'] = 'Nowy zbiór filtrów'; program/include/rcube_imap.php
@@ -2426,9 +2426,11 @@ * @param rcube_message_part $o_part Part object created by get_structure() * @param mixed $print True to print part, ressource to write part contents in * @param resource $fp File pointer to save the message part * @param boolean $skip_charset_conv Disables charset conversion * * @return string Message/part body if not printed */ function &get_message_part($uid, $part=1, $o_part=NULL, $print=NULL, $fp=NULL) function &get_message_part($uid, $part=1, $o_part=NULL, $print=NULL, $fp=NULL, $skip_charset_conv=false) { // get part encoding if not provided if (!is_object($o_part)) { @@ -2458,10 +2460,13 @@ return true; } // convert charset (if text or message part) and part's charset is specified if ($body && $o_part->charset && preg_match('/^(text|message)$/', $o_part->ctype_primary) // convert charset (if text or message part) if ($body && !$skip_charset_conv && preg_match('/^(text|message)$/', $o_part->ctype_primary) ) { if (!$o_part->charset || strtoupper($o_part->charset) == 'US-ASCII') { $o_part->charset = $this->default_charset; } $body = rcube_charset_convert($body, $o_part->charset); } program/include/rcube_imap_generic.php
@@ -964,6 +964,16 @@ list($mbox, $items) = $this->tokenizeResponse($response, 2); // Fix for #1487859. Some buggy server returns not quoted // folder name with spaces. Let's try to handle this situation if (!is_array($items) && ($pos = strpos($response, '(')) !== false) { $response = substr($response, $pos); $items = $this->tokenizeResponse($response, 1); if (!is_array($items)) { return $result; } } for ($i=0, $len=count($items); $i<$len; $i += 2) { $result[$items[$i]] = (int) $items[$i+1]; } @@ -1569,36 +1579,21 @@ if (preg_match('/^\* [0-9]+ FETCH \((.*) BODY/sU', $line, $matches)) { $str = $matches[1]; // swap parents with quotes, then explode $str = preg_replace('/[()]/', '"', $str); $a = rcube_explode_quoted_string(' ', $str); // did we get the right number of replies? $parts_count = count($a); if ($parts_count>=6) { for ($i=0; $i<$parts_count; $i=$i+2) { if ($a[$i] == 'UID') { $result[$id]->uid = intval($a[$i+1]); } else if ($a[$i] == 'RFC822.SIZE') { $result[$id]->size = intval($a[$i+1]); } else if ($a[$i] == 'INTERNALDATE') { $time_str = $a[$i+1]; } else if ($a[$i] == 'FLAGS') { $flags_str = $a[$i+1]; } while (list($name, $value) = $this->tokenizeResponse($str, 2)) { if ($name == 'UID') { $result[$id]->uid = intval($value); } $time_str = str_replace('"', '', $time_str); // if time is gmt... $time_str = str_replace('GMT','+0000',$time_str); $result[$id]->internaldate = $time_str; $result[$id]->timestamp = $this->StrToTime($time_str); $result[$id]->date = $time_str; else if ($name == 'RFC822.SIZE') { $result[$id]->size = intval($value); } else if ($name == 'INTERNALDATE') { $result[$id]->internaldate = $value; $result[$id]->date = $value; $result[$id]->timestamp = $this->StrToTime($value); } else if ($name == 'FLAGS') { $flags_a = $value; } } // BODYSTRUCTURE @@ -1646,7 +1641,7 @@ // handle FLAGS reply after headers (AOL, Zimbra?) if (preg_match('/\s+FLAGS \((.*)\)\)$/', $line, $matches)) { $flags_str = $matches[1]; $flags_a = $this->tokenizeResponse($matches[1]); break; } @@ -1670,10 +1665,10 @@ // create array with header field:data while (list($lines_key, $str) = each($lines)) { list($field, $string) = $this->splitHeaderLine($str); list($field, $string) = explode(':', $str, 2); $field = strtolower($field); $string = preg_replace('/\n\s*/', ' ', $string); $string = preg_replace('/\n[\t\s]*/', ' ', trim($string)); switch ($field) { case 'date'; @@ -1737,32 +1732,31 @@ } // process flags if (!empty($flags_str)) { $flags_str = preg_replace('/[\\\"]/', '', $flags_str); $flags_a = explode(' ', $flags_str); if (!empty($flags_a)) { foreach ($flags_a as $flag) { $flag = str_replace('\\', '', $flag); $result[$id]->flags[] = $flag; if (is_array($flags_a)) { foreach($flags_a as $flag) { $flag = strtoupper($flag); if ($flag == 'SEEN') { $result[$id]->seen = true; } else if ($flag == 'DELETED') { $result[$id]->deleted = true; } else if ($flag == 'RECENT') { $result[$id]->recent = true; } else if ($flag == 'ANSWERED') { $result[$id]->answered = true; } else if ($flag == '$FORWARDED') { $result[$id]->forwarded = true; } else if ($flag == 'DRAFT') { $result[$id]->is_draft = true; } else if ($flag == '$MDNSENT') { $result[$id]->mdn_sent = true; } else if ($flag == 'FLAGGED') { $result[$id]->flagged = true; } switch (strtoupper($flag)) { case 'SEEN': $result[$id]->seen = true; break; case 'DELETED': $result[$id]->deleted = true; break; case 'ANSWERED': $result[$id]->answered = true; break; case '$FORWARDED': $result[$id]->forwarded = true; break; case '$MDNSENT': $result[$id]->mdn_sent = true; break; case 'FLAGGED': $result[$id]->flagged = true; break; } $result[$id]->flags = $flags_a; } } } @@ -3297,9 +3291,10 @@ { // support non-standard "GMTXXXX" literal $date = preg_replace('/GMT\s*([+-][0-9]+)/', '\\1', $date); // if date parsing fails, we have a date in non-rfc format. // remove token from the end and try again while ((($ts = @strtotime($date))===false) || ($ts < 0)) { while (($ts = intval(@strtotime($date))) <= 0) { $d = explode(' ', $date); array_pop($d); if (!$d) { @@ -3311,17 +3306,6 @@ $ts = (int) $ts; return $ts < 0 ? 0 : $ts; } private function splitHeaderLine($string) { $pos = strpos($string, ':'); if ($pos>0) { $res[0] = substr($string, 0, $pos); $res[1] = trim(substr($string, $pos+1)); return $res; } return $string; } private function parseCapability($str, $trusted=false) program/include/rcube_mdb2.php
@@ -553,15 +553,7 @@ */ function fromunixtime($timestamp) { switch($this->db_provider) { case 'mysqli': case 'mysql': case 'sqlite': return sprintf("FROM_UNIXTIME(%d)", $timestamp); default: return date("'Y-m-d H:i:s'", $timestamp); } return date("'Y-m-d H:i:s'", $timestamp); } program/include/rcube_message.php
@@ -725,7 +725,9 @@ $line = $prefix . rc_wordwrap($line, $length - $level - 2, " \r\n$prefix "); } else if ($line) { $line = ' ' . rc_wordwrap(rtrim($line), $length - 2, " \r\n "); $line = rc_wordwrap(rtrim($line), $length - 2, " \r\n"); // space-stuffing $line = preg_replace('/(^|\r\n)(From| |>)/', '\\1 \\2', $line); } $text[$idx] = $line; program/js/app.js
@@ -2994,11 +2994,11 @@ this.compose_field_hash = function(save) { // check input fields var value_to = $("[name='_to']").val(); var value_cc = $("[name='_cc']").val(); var value_bcc = $("[name='_bcc']").val(); var value_subject = $("[name='_subject']").val(); var str = ''; var ed, str = '', value_to = $("[name='_to']").val(), value_cc = $("[name='_cc']").val(), value_bcc = $("[name='_bcc']").val(), value_subject = $("[name='_subject']").val(); if (value_to) str += value_to+':'; @@ -3009,9 +3009,8 @@ if (value_subject) str += value_subject+':'; var editor = tinyMCE.get(this.env.composebody); if (editor) str += editor.getContent(); if (window.tinyMCE && (ed = tinyMCE.get(this.env.composebody))) str += ed.getContent(); else str += $("[name='_message']").val(); @@ -4622,7 +4621,7 @@ var current_li, target_li; if ((current_li = this.get_folder_li(old, prefix))) { $(current_li).removeClass('selected').removeClass('unfocused'); $(current_li).removeClass('selected').addClass('unfocused'); } if ((target_li = this.get_folder_li(name, prefix))) { $(target_li).removeClass('unfocused').addClass('selected'); program/lib/html2text.php
@@ -572,9 +572,16 @@ */ function _convert_pre(&$text) { // get the content of PRE element while (preg_match('/<pre[^>]*>(.*)<\/pre>/ismU', $text, $matches)) { $result = preg_replace($this->pre_search, $this->pre_replace, $matches[1]); $text = preg_replace('/<pre[^>]*>.*<\/pre>/ismU', '<div><br>' . $result . '<br></div>', $text, 1); // convert the content $this->pre_content = sprintf('<div><br>%s<br></div>', preg_replace($this->pre_search, $this->pre_replace, $matches[1])); // replace the content (use callback because content can contain $0 variable) $text = preg_replace_callback('/<pre[^>]*>.*<\/pre>/ismU', array('html2text', '_preg_pre_callback'), $text, 1); // free memory $this->pre_content = ''; } } @@ -639,9 +646,8 @@ * * @param array PREG matches * @return string * @access private */ function _preg_callback($matches) private function _preg_callback($matches) { switch($matches[1]) { case 'b': @@ -659,13 +665,23 @@ } /** * Callback function for preg_replace_callback use in PRE content handler. * * @param array PREG matches * @return string */ private function _preg_pre_callback($matches) { return $this->pre_content; } /** * Strtoupper multibyte wrapper function * * @param string * @return string * @access private */ function _strtoupper($str) private function _strtoupper($str) { if (function_exists('mb_strtoupper')) return mb_strtoupper($str); program/steps/mail/func.inc
@@ -726,71 +726,74 @@ $body = preg_replace_callback($replacer->mailto_pattern, array($replacer, 'mailto_callback'), $body); // split body into single lines $a_lines = preg_split('/\r?\n/', $body); $body = preg_split('/\r?\n/', $body); $quote_level = 0; $last = -1; // find/mark quoted lines... for ($n=0, $cnt=count($a_lines); $n < $cnt; $n++) { if ($a_lines[$n][0] == '>' && preg_match('/^(>+\s*)+/', $a_lines[$n], $regs)) { for ($n=0, $cnt=count($body); $n < $cnt; $n++) { if ($body[$n][0] == '>' && preg_match('/^(>+\s*)+/', $body[$n], $regs)) { $q = strlen(preg_replace('/\s/', '', $regs[0])); $a_lines[$n] = substr($a_lines[$n], strlen($regs[0])); $body[$n] = substr($body[$n], strlen($regs[0])); if ($q > $quote_level) $a_lines[$n] = $replacer->get_replacement($replacer->add( str_repeat('<blockquote>', $q - $quote_level))) . $a_lines[$n]; else if ($q < $quote_level) $a_lines[$n] = $replacer->get_replacement($replacer->add( str_repeat('</blockquote>', $quote_level - $q))) . $a_lines[$n]; if ($q > $quote_level) { $body[$n] = $replacer->get_replacement($replacer->add( str_repeat('<blockquote>', $q - $quote_level))) . $body[$n]; } else if ($q < $quote_level) { $body[$n] = $replacer->get_replacement($replacer->add( str_repeat('</blockquote>', $quote_level - $q))) . $body[$n]; } else if ($flowed) { // previous line is flowed if (isset($a_lines[$last]) && $a_lines[$n] && $a_lines[$last][strlen($a_lines[$last])-1] == ' ') { if (isset($body[$last]) && $body[$n] && $body[$last][strlen($body[$last])-1] == ' ') { // merge lines $a_lines[$last] .= $a_lines[$n]; unset($a_lines[$n]); $body[$last] .= $body[$n]; unset($body[$n]); } else else { $last = $n; } } } else { $q = 0; if ($flowed) { // sig separator - line is fixed if ($a_lines[$n] == '-- ') { $last = $n; if ($body[$n] == '-- ') { $last = $last_sig = $n; } else { // remove space-stuffing if ($a_lines[$n][0] == ' ') $a_lines[$n] = substr($a_lines[$n], 1); if ($body[$n][0] == ' ') $body[$n] = substr($body[$n], 1); // previous line is flowed? if (isset($a_lines[$last]) && $a_lines[$n] && $a_lines[$last] != '-- ' && $a_lines[$last][strlen($a_lines[$last])-1] == ' ' if (isset($body[$last]) && $body[$n] && $last != $last_sig && $body[$last][strlen($body[$last])-1] == ' ' ) { $a_lines[$last] .= $a_lines[$n]; unset($a_lines[$n]); $body[$last] .= $body[$n]; unset($body[$n]); } else { $last = $n; } } if ($quote_level > 0) $a_lines[$last] = $replacer->get_replacement($replacer->add( str_repeat('</blockquote>', $quote_level))) . $a_lines[$last]; $body[$last] = $replacer->get_replacement($replacer->add( str_repeat('</blockquote>', $quote_level))) . $body[$last]; } else if ($quote_level > 0) $a_lines[$n] = $replacer->get_replacement($replacer->add( str_repeat('</blockquote>', $quote_level))) . $a_lines[$n]; $body[$n] = $replacer->get_replacement($replacer->add( str_repeat('</blockquote>', $quote_level))) . $body[$n]; } $quote_level = $q; } $body = join("\n", $a_lines); $body = join("\n", $body); // quote plain text (don't use Q() here, to display entities "as is") $table = get_html_translation_table(HTML_SPECIALCHARS); program/steps/settings/save_prefs.inc
@@ -97,10 +97,10 @@ break; } $data = rcmail::get_instance()->plugins->exec_hook('preferences_save', $plugin = rcmail::get_instance()->plugins->exec_hook('preferences_save', array('prefs' => $a_user_prefs, 'section' => $CURR_SECTION)); $a_user_prefs = $data['prefs']; $a_user_prefs = $plugin['prefs']; // don't override these parameters foreach ((array)$CONFIG['dont_override'] as $p) @@ -159,10 +159,17 @@ break; } if ($USER->save_prefs($a_user_prefs)) // Save preferences if (!$plugin['abort']) $saved = $USER->save_prefs($a_user_prefs); else $saved = $plugin['result']; if ($saved) $OUTPUT->show_message('successfullysaved', 'confirmation'); else $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsaving', 'error'); // display the form again rcmail_overwrite_action('edit-prefs');