From 4dfae96dcdfba93a8b03db2d0422766b20adf77d Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Fri, 5 Apr 2013 12:48:36 +0200 Subject: [PATCH 1/4] Fix copying messages to a folder with "empty" name e.g. "0", better error handling --- program/steps/mail/copy.inc | 8 ++++---- program/steps/mail/mark.inc | 10 +++++----- program/steps/mail/move_del.inc | 2 ++ 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/program/steps/mail/copy.inc b/program/steps/mail/copy.inc index a72378b0e..876657485 100644 --- a/program/steps/mail/copy.inc +++ b/program/steps/mail/copy.inc @@ -24,10 +24,10 @@ if (!$OUTPUT->ajax_call) return; // move messages -if (!empty($_POST['_uid']) && !empty($_POST['_target_mbox'])) { - $uids = get_input_value('_uid', RCUBE_INPUT_POST); +if (!empty($_POST['_uid']) && strlen($_POST['_target_mbox'])) { + $uids = get_input_value('_uid', RCUBE_INPUT_POST); $target = get_input_value('_target_mbox', RCUBE_INPUT_POST, true); - $mbox = get_input_value('_mbox', RCUBE_INPUT_POST, true); + $mbox = get_input_value('_mbox', RCUBE_INPUT_POST, true); $copied = $RCMAIL->storage->copy_message($uids, $target, $mbox); @@ -47,7 +47,7 @@ if (!empty($_POST['_uid']) && !empty($_POST['_target_mbox'])) { } // unknown action or missing query param else { - exit; + $OUTPUT->show_message('internalerror', 'error'); } // send response diff --git a/program/steps/mail/mark.inc b/program/steps/mail/mark.inc index c220fc5c4..dfc892ea1 100644 --- a/program/steps/mail/mark.inc +++ b/program/steps/mail/mark.inc @@ -113,7 +113,7 @@ if (($uids = get_input_value('_uid', RCUBE_INPUT_POST)) && ($flag = get_input_va $OUTPUT->command('set_rowcount', rcmail_get_messagecount_text($msg_count), $mbox); if ($threading) { - $count = get_input_value('_count', RCUBE_INPUT_POST); + $count = get_input_value('_count', RCUBE_INPUT_POST); } // add new rows from next page (if any) @@ -125,9 +125,9 @@ if (($uids = get_input_value('_uid', RCUBE_INPUT_POST)) && ($flag = get_input_va } } } - - $OUTPUT->send(); +} +else { + $OUTPUT->show_message('internalerror', 'error'); } -exit; - +$OUTPUT->send(); diff --git a/program/steps/mail/move_del.inc b/program/steps/mail/move_del.inc index 3fc6ac5a7..e21ba2c6b 100644 --- a/program/steps/mail/move_del.inc +++ b/program/steps/mail/move_del.inc @@ -74,6 +74,8 @@ else if ($RCMAIL->action=='delete' && !empty($_POST['_uid'])) { } // unknown action or missing query param else { + $OUTPUT->show_message('internalerror', 'error'); + $OUTPUT->send(); exit; } From ad827b911782d172da518303555786851f000322 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Fri, 5 Apr 2013 13:36:38 +0200 Subject: [PATCH 2/4] Fix selecting collapsed rows on select-all (#1489036) --- CHANGELOG | 1 + program/js/list.js | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index c21743dfc..8a04931e6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ CHANGELOG Roundcube Webmail =========================== +- Fix selecting collapsed rows on select-all (#1489036) - Fix possible header duplicates when using additional headers (#1489033) - Fix session issues with use_https=true (#1488986) - Fix blockquote width in sent mail (#1489031) diff --git a/program/js/list.js b/program/js/list.js index 8b4857d6d..5aa9331b0 100644 --- a/program/js/list.js +++ b/program/js/list.js @@ -829,7 +829,7 @@ select_all: function(filter) for (n in this.rows) { if (!filter || this.rows[n][filter] == true) { this.last_selected = n; - this.highlight_row(n, true); + this.highlight_row(n, true, true); } else { $(this.rows[n].obj).removeClass('selected').removeClass('unfocused'); @@ -924,7 +924,7 @@ get_single_selection: function() /** * Highlight/unhighlight a row */ -highlight_row: function(id, multiple) +highlight_row: function(id, multiple, norecur) { if (!this.rows[id]) return; @@ -940,7 +940,7 @@ highlight_row: function(id, multiple) if (!this.in_selection(id)) { // select row this.selection.push(id); $(this.rows[id].obj).addClass('selected'); - if (!this.rows[id].expanded) + if (!norecur && !this.rows[id].expanded) this.highlight_children(id, true); } else { // unselect row @@ -950,7 +950,7 @@ highlight_row: function(id, multiple) this.selection = a_pre.concat(a_post); $(this.rows[id].obj).removeClass('selected').removeClass('unfocused'); - if (!this.rows[id].expanded) + if (!norecur && !this.rows[id].expanded) this.highlight_children(id, false); } } @@ -968,7 +968,7 @@ highlight_children: function(id, status) for (i=0; i Date: Fri, 5 Apr 2013 14:59:13 +0200 Subject: [PATCH 3/4] Fix selecting collapsed rows when using selection with Shift/Ctrl key --- program/js/list.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/program/js/list.js b/program/js/list.js index 5aa9331b0..cf62a7c14 100644 --- a/program/js/list.js +++ b/program/js/list.js @@ -780,10 +780,16 @@ shift_select: function(id, control) if (!this.rows[this.shift_start] || !this.selection.length) this.shift_start = id; - var n, from_rowIndex = this.rows[this.shift_start].obj.rowIndex, - to_rowIndex = this.rows[id].obj.rowIndex, - i = ((from_rowIndex < to_rowIndex)? from_rowIndex : to_rowIndex), - j = ((from_rowIndex > to_rowIndex)? from_rowIndex : to_rowIndex); + var n, i, j, to_row = this.rows[id], + from_rowIndex = this.rows[this.shift_start].obj.rowIndex, + to_rowIndex = to_row.obj.rowIndex; + + if (!to_row.expanded && to_row.has_children) + if (to_row = this.rows[(this.row_children(id)).pop()]) + to_rowIndex = to_row.obj.rowIndex; + + i = ((from_rowIndex < to_rowIndex) ? from_rowIndex : to_rowIndex), + j = ((from_rowIndex > to_rowIndex) ? from_rowIndex : to_rowIndex); // iterate through the entire message list for (n in this.rows) { From 4fdaa02ac724e597479a4a48388a8a10101000fd Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Sat, 6 Apr 2013 19:28:47 +0200 Subject: [PATCH 4/4] Fix handling of invalid characters in message headers and output (#1489032) --- CHANGELOG | 1 + program/lib/Roundcube/html.php | 12 +++++++++++- program/lib/Roundcube/rcube_message.php | 15 ++++++--------- program/lib/Roundcube/rcube_message_header.php | 7 ++++++- program/steps/mail/compose.inc | 8 ++++---- program/steps/mail/func.inc | 2 +- program/steps/mail/show.inc | 2 +- 7 files changed, 30 insertions(+), 17 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 8a04931e6..a9121fca0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ CHANGELOG Roundcube Webmail =========================== +- Fix handling of invalid characters in message headers and output (#1489032) - Fix selecting collapsed rows on select-all (#1489036) - Fix possible header duplicates when using additional headers (#1489033) - Fix session issues with use_https=true (#1488986) diff --git a/program/lib/Roundcube/html.php b/program/lib/Roundcube/html.php index 592720308..7b30e60cb 100644 --- a/program/lib/Roundcube/html.php +++ b/program/lib/Roundcube/html.php @@ -35,6 +35,7 @@ class html public static $common_attrib = array('id','class','style','title','align'); public static $containers = array('iframe','div','span','p','h1','h2','h3','form','textarea','table','thead','tbody','tr','th','td','style','script'); + /** * Constructor * @@ -332,7 +333,16 @@ class html */ public static function quote($str) { - return @htmlspecialchars($str, ENT_COMPAT, RCUBE_CHARSET); + static $flags; + + if (!$flags) { + $flags = ENT_COMPAT; + if (defined('ENT_SUBSTITUTE')) { + $flags |= ENT_SUBSTITUTE; + } + } + + return @htmlspecialchars($str, $flags, RCUBE_CHARSET); } } diff --git a/program/lib/Roundcube/rcube_message.php b/program/lib/Roundcube/rcube_message.php index 41a114f7f..69735fc52 100644 --- a/program/lib/Roundcube/rcube_message.php +++ b/program/lib/Roundcube/rcube_message.php @@ -85,12 +85,13 @@ class rcube_message $this->headers = $this->storage->get_message($uid); - if (!$this->headers) + if (!$this->headers) { return; + } $this->mime = new rcube_mime($this->headers->charset); - $this->subject = $this->mime->decode_mime_string($this->headers->subject); + $this->subject = $this->headers->get('subject'); list(, $this->sender) = each($this->mime->decode_address_list($this->headers->from, 1)); $this->set_safe((intval($_GET['_safe']) || $_SESSION['safe_messages'][$this->folder.':'.$uid])); @@ -125,15 +126,11 @@ class rcube_message */ public function get_header($name, $raw = false) { - if (empty($this->headers)) + if (empty($this->headers)) { return null; + } - if ($this->headers->$name) - $value = $this->headers->$name; - else if ($this->headers->others[$name]) - $value = $this->headers->others[$name]; - - return $raw ? $value : $this->mime->decode_header($value); + return $this->headers->get($name, !$raw); } diff --git a/program/lib/Roundcube/rcube_message_header.php b/program/lib/Roundcube/rcube_message_header.php index 274ae7f9f..2c5e2b6c8 100644 --- a/program/lib/Roundcube/rcube_message_header.php +++ b/program/lib/Roundcube/rcube_message_header.php @@ -215,7 +215,12 @@ class rcube_message_header $value = $this->others[$name]; } - return $decode ? rcube_mime::decode_header($value, $this->charset) : $value; + if ($decode) { + $value = rcube_mime::decode_header($value, $this->charset); + $value = rcube_charset::clean($value); + } + + return $value; } /** diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc index 36c6d9622..b787ca101 100644 --- a/program/steps/mail/compose.inc +++ b/program/steps/mail/compose.inc @@ -220,9 +220,9 @@ if (!empty($msg_uid) && empty($COMPOSE['as_attachment'])) } } else if ($compose_mode == RCUBE_COMPOSE_DRAFT) { - if ($MESSAGE->headers->others['x-draft-info']) { + if ($draft_info = $MESSAGE->headers->get('x-draft-info')) { // get reply_uid/forward_uid to flag the original message when sending - $info = rcmail_draftinfo_decode($MESSAGE->headers->others['x-draft-info']); + $info = rcmail_draftinfo_decode($draft_info); if ($info['type'] == 'reply') $COMPOSE['reply_uid'] = $info['uid']; @@ -239,8 +239,8 @@ if (!empty($msg_uid) && empty($COMPOSE['as_attachment'])) } } - if ($MESSAGE->headers->in_reply_to) - $COMPOSE['reply_msgid'] = '<'.$MESSAGE->headers->in_reply_to.'>'; + if ($in_reply_to = $MESSAGE->headers->get('in-reply-to')) + $COMPOSE['reply_msgid'] = '<' . $in_reply_to . '>'; $COMPOSE['references'] = $MESSAGE->headers->references; } diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc index 274c40b5c..6333cf46d 100644 --- a/program/steps/mail/func.inc +++ b/program/steps/mail/func.inc @@ -896,7 +896,7 @@ function rcmail_washtml_callback($tagname, $attrib, $content, $washtml) * return table with message headers */ function rcmail_message_headers($attrib, $headers=null) - { +{ global $OUTPUT, $MESSAGE, $PRINT_MODE, $RCMAIL; static $sa_attrib; diff --git a/program/steps/mail/show.inc b/program/steps/mail/show.inc index 552c180f5..1947c0f29 100644 --- a/program/steps/mail/show.inc +++ b/program/steps/mail/show.inc @@ -109,7 +109,7 @@ if ($uid) { $OUTPUT->set_env('skip_deleted', true); if ($CONFIG['display_next']) $OUTPUT->set_env('display_next', true); - if ($MESSAGE->headers->others['list-post']) + if ($MESSAGE->headers->get('list-post', false)) $OUTPUT->set_env('list_post', true); if ($CONFIG['forward_attachment']) $OUTPUT->set_env('forward_attachment', true);