From f06aa8058b7e32ba32d4551074b6e0b8a300f751 Mon Sep 17 00:00:00 2001 From: Thomas Bruederli <thomas@roundcube.net> Date: Mon, 21 Oct 2013 15:02:40 -0400 Subject: [PATCH] Bump version after security fix --- program/steps/mail/compose.inc | 132 +++++++++++++++++++++++++++----------------- 1 files changed, 81 insertions(+), 51 deletions(-) diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc index d5356e0..064983a 100644 --- a/program/steps/mail/compose.inc +++ b/program/steps/mail/compose.inc @@ -29,7 +29,6 @@ define('RCUBE_COMPOSE_EDIT', 0x0109); $MESSAGE_FORM = null; -$MESSAGE = null; $COMPOSE_ID = get_input_value('_id', RCUBE_INPUT_GET); $COMPOSE = null; @@ -119,7 +118,11 @@ } // redirect to a unique URL with all parameters stored in session - $OUTPUT->redirect(array('_action' => 'compose', '_id' => $COMPOSE['id'])); + $OUTPUT->redirect(array( + '_action' => 'compose', + '_id' => $COMPOSE['id'], + '_search' => $_REQUEST['_search'], + )); } @@ -181,7 +184,7 @@ $MESSAGE = new rcube_message($msg_uid); // make sure message is marked as read - if ($MESSAGE && $MESSAGE->headers && empty($MESSAGE->headers->flags['SEEN'])) + if ($MESSAGE->headers && empty($MESSAGE->headers->flags['SEEN'])) $RCMAIL->storage->set_flag($msg_uid, 'SEEN'); if (!empty($MESSAGE->headers->charset)) @@ -241,6 +244,9 @@ $MESSAGE->forward_attachment = true; } } +else { + $MESSAGE = new stdClass(); +} $MESSAGE->compose = array(); @@ -249,7 +255,8 @@ if (count($MESSAGE->identities)) { foreach ($MESSAGE->identities as $idx => $ident) { - $email = mb_strtolower(rcube_idn_to_utf8($ident['email'])); + $ident['email'] = format_email($ident['email']); + $email = format_email(rcube_idn_to_utf8($ident['email'])); $MESSAGE->identities[$idx]['email_ascii'] = $ident['email']; $MESSAGE->identities[$idx]['ident'] = format_email_recipient($ident['email'], $ident['name']); @@ -274,7 +281,7 @@ $a_to = rcube_mime::decode_address_list($MESSAGE->headers->to, null, true, $MESSAGE->headers->charset); foreach ($a_to as $addr) { if (!empty($addr['mailto'])) { - $a_recipients[] = strtolower($addr['mailto']); + $a_recipients[] = format_email($addr['mailto']); $a_names[] = $addr['name']; } } @@ -283,7 +290,7 @@ $a_cc = rcube_mime::decode_address_list($MESSAGE->headers->cc, null, true, $MESSAGE->headers->charset); foreach ($a_cc as $addr) { if (!empty($addr['mailto'])) { - $a_recipients[] = strtolower($addr['mailto']); + $a_recipients[] = format_email($addr['mailto']); $a_names[] = $addr['name']; } } @@ -291,16 +298,12 @@ } $from_idx = null; - $default_identity = null; + $found_idx = null; + $default_identity = 0; // default identity is always first on the list $return_path = $MESSAGE->headers->others['return-path']; // Select identity foreach ($MESSAGE->identities as $idx => $ident) { - // save default identity ID - if ($ident['standard']) { - $default_identity = $idx; - } - // use From header if (in_array($compose_mode, array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT))) { if ($MESSAGE->headers->from == $ident['ident']) { @@ -315,11 +318,20 @@ } // use replied message recipients else if (($found = array_search($ident['email_ascii'], $a_recipients)) !== false) { - // match identity name, prefer default identity - if ($from_idx === null || ($a_names[$found] && $ident['name'] && $a_names[$found] == $ident['name'])) { + if ($found_idx === null) { + $found_idx = $idx; + } + // match identity name + if ($a_names[$found] && $ident['name'] && $a_names[$found] == $ident['name']) { $from_idx = $idx; + break; } } + } + + // If matching by name+address doesn't found any amtches, get first found address (identity) + if ($from_idx === null) { + $from_idx = $found_idx; } // Fallback using Return-Path @@ -332,12 +344,7 @@ } } - // Still no ID, use default/first identity - if ($from_idx === null) { - $from_idx = $default_identity !== null ? $default_identity : key(reset($MESSAGE->identities)); - } - - $ident = $MESSAGE->identities[$from_idx]; + $ident = $MESSAGE->identities[$from_idx !== null ? $from_idx : $default_identity]; $from_id = $ident['identity_id']; $MESSAGE->compose['from_email'] = $ident['email']; @@ -408,11 +415,11 @@ else if (in_array($compose_mode, array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT))) { // get drafted headers if ($header=='to' && !empty($MESSAGE->headers->to)) - $fvalue = $MESSAGE->get_header('to'); + $fvalue = $MESSAGE->get_header('to', true); else if ($header=='cc' && !empty($MESSAGE->headers->cc)) - $fvalue = $MESSAGE->get_header('cc'); + $fvalue = $MESSAGE->get_header('cc', true); else if ($header=='bcc' && !empty($MESSAGE->headers->bcc)) - $fvalue = $MESSAGE->get_header('bcc'); + $fvalue = $MESSAGE->get_header('bcc', true); else if ($header=='replyto' && !empty($MESSAGE->headers->others['mail-reply-to'])) $fvalue = $MESSAGE->get_header('mail-reply-to'); else if ($header=='replyto' && !empty($MESSAGE->headers->replyto)) @@ -430,7 +437,7 @@ if (empty($addr_part['mailto'])) continue; - $mailto = mb_strtolower(rcube_idn_to_utf8($addr_part['mailto'])); + $mailto = format_email(rcube_idn_to_utf8($addr_part['mailto'])); if (!in_array($mailto, $a_recipients) && ($header == 'to' || empty($MESSAGE->compose['from_email']) || $mailto != $MESSAGE->compose['from_email']) @@ -526,7 +533,7 @@ function rcmail_compose_header_from($attrib) { - global $MESSAGE, $OUTPUT; + global $MESSAGE, $OUTPUT, $RCMAIL, $compose_mode; // pass the following attributes to the form class $field_attrib = array('name' => '_from'); @@ -537,6 +544,8 @@ if (count($MESSAGE->identities)) { $a_signatures = array(); + $separator = $RCMAIL->config->get('sig_above') + && ($compose_mode == RCUBE_COMPOSE_REPLY || $compose_mode == RCUBE_COMPOSE_FORWARD) ? '---' : '-- '; $field_attrib['onchange'] = JS_OBJECT_NAME.".change_identity(this)"; $select_from = new html_select($field_attrib); @@ -550,13 +559,27 @@ // add signature to array if (!empty($sql_arr['signature']) && empty($COMPOSE['param']['nosig'])) { - $a_signatures[$identity_id]['text'] = $sql_arr['signature']; - $a_signatures[$identity_id]['is_html'] = ($sql_arr['html_signature'] == 1) ? true : false; - if ($a_signatures[$identity_id]['is_html']) - { - $h2t = new html2text($a_signatures[$identity_id]['text'], false, false); - $a_signatures[$identity_id]['plain_text'] = trim($h2t->get_text()); + $text = $html = $sql_arr['signature']; + + if ($sql_arr['html_signature']) { + $h2t = new html2text($sql_arr['signature'], false, false); + $text = trim($h2t->get_text()); } + else { + $html = htmlentities($html, ENT_NOQUOTES, RCMAIL_CHARSET); + } + + if (!preg_match('/^--[ -]\r?\n/m', $text)) { + $text = $separator . "\n" . $text; + $html = $separator . "<br>" . $html; + } + + if (!$sql_arr['html_signature']) { + $html = "<pre>" . $html . "</pre>"; + } + + $a_signatures[$identity_id]['text'] = $text; + $a_signatures[$identity_id]['html'] = $html; } } @@ -626,7 +649,8 @@ if (!empty($MESSAGE->parts)) { foreach ($MESSAGE->parts as $part) { - if ($part->type != 'content' || !$part->size) { + // skip no-content and attachment parts (#1488557) + if ($part->type != 'content' || !$part->size || $MESSAGE->is_attachment($part)) { continue; } @@ -662,9 +686,9 @@ if ($isHtml && preg_match('#<img src="\./program/blocked\.gif"#', $body)) { if ($attachment = rcmail_save_image('program/blocked.gif', 'image/gif')) { $COMPOSE['attachments'][$attachment['id']] = $attachment; - $body = preg_replace('#\./program/blocked\.gif#', - $RCMAIL->comm_path.'&_action=display-attachment&_file=rcmfile'.$attachment['id'].'&_id='.$COMPOSE['id'], - $body); + $url = sprintf('%s&_id=%s&_action=display-attachment&_file=rcmfile%s', + $RCMAIL->comm_path, $COMPOSE['id'], $attachment['id']); + $body = preg_replace('#\./program/blocked\.gif#', $url, $body); } } @@ -764,6 +788,7 @@ // If desired, set this textarea to be editable by TinyMCE if ($isHtml) { + $MESSAGE_BODY = htmlentities($MESSAGE_BODY, ENT_NOQUOTES, RCMAIL_CHARSET); $attrib['class'] = 'mce_editor'; $textarea = new html_textarea($attrib); $out .= $textarea->show($MESSAGE_BODY); @@ -813,6 +838,9 @@ if (!$spellcheck_langs[$lang]) $lang = 'en'; + $OUTPUT->set_env('spell_langs', $spellcheck_langs); + $OUTPUT->set_env('spell_lang', $lang); + $editor_lang_set = array(); foreach ($spellcheck_langs as $key => $name) { $editor_lang_set[] = ($key == $lang ? '+' : '') . JQ($name).'='.JQ($key); @@ -830,7 +858,7 @@ "googie.lang_learn_word = \"%s\";\n". "googie.setLanguages(%s);\n". "googie.setCurrentLanguage('%s');\n". - "googie.setSpellContainer('spellcheck-control');\n". + "googie.setDecoration(false);\n". "googie.decorateTextarea('%s');\n". "%s.set_env('spellcheck', googie);", $RCMAIL->output->get_skin_path(), @@ -873,9 +901,10 @@ if (!$bodyIsHtml) { $body = preg_replace('/\r?\n/', "\n", $body); + $body = trim($body, "\n"); // soft-wrap and quote message text - $body = rcmail_wrap_and_quote(rtrim($body, "\n"), $LINE_LENGTH); + $body = rcmail_wrap_and_quote($body, $LINE_LENGTH); $prefix .= "\n"; $suffix = ''; @@ -919,8 +948,7 @@ $date = format_date($MESSAGE->headers->date, $RCMAIL->config->get('date_long')); $charset = $RCMAIL->output->get_charset(); - if (!$bodyIsHtml) - { + if (!$bodyIsHtml) { $prefix = "\n\n\n-------- " . rcube_label('originalmessage') . " --------\n"; $prefix .= rcube_label('subject') . ': ' . $MESSAGE->subject . "\n"; $prefix .= rcube_label('date') . ': ' . $date . "\n"; @@ -933,9 +961,9 @@ $prefix .= rcube_label('replyto') . ': ' . $MESSAGE->get_header('replyto') . "\n"; $prefix .= "\n"; + $body = trim($body, "\r\n"); } - else - { + else { // set is_safe flag (we need this for html body washing) rcmail_check_safe($MESSAGE); // clean up html tags @@ -950,18 +978,18 @@ "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>", rcube_label('subject'), Q($MESSAGE->subject), rcube_label('date'), Q($date), - rcube_label('from'), htmlspecialchars(Q($MESSAGE->get_header('from'), 'replace'), ENT_COMPAT, $charset), - rcube_label('to'), htmlspecialchars(Q($MESSAGE->get_header('to'), 'replace'), ENT_COMPAT, $charset)); + rcube_label('from'), Q($MESSAGE->get_header('from'), 'replace'), + rcube_label('to'), Q($MESSAGE->get_header('to'), 'replace')); if ($MESSAGE->headers->cc) $prefix .= sprintf("<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>", rcube_label('cc'), - htmlspecialchars(Q($MESSAGE->get_header('cc'), 'replace'), ENT_COMPAT, $charset)); + Q($MESSAGE->get_header('cc'), 'replace')); if ($MESSAGE->headers->replyto && $MESSAGE->headers->replyto != $MESSAGE->headers->from) $prefix .= sprintf("<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>", rcube_label('replyto'), - htmlspecialchars(Q($MESSAGE->get_header('replyto'), 'replace'), ENT_COMPAT, $charset)); + Q($MESSAGE->get_header('replyto'), 'replace')); $prefix .= "</tbody></table><br>"; } @@ -1041,7 +1069,8 @@ if (!$skip && ($attachment = rcmail_save_attachment($message, $pid))) { $COMPOSE['attachments'][$attachment['id']] = $attachment; if ($bodyIsHtml && ($part->content_id || $part->content_location)) { - $url = $RCMAIL->comm_path.'&_action=display-attachment&_file=rcmfile'.$attachment['id'].'&_id='.$COMPOSE['id']; + $url = sprintf('%s&_id=%s&_action=display-attachment&_file=rcmfile%s', + $RCMAIL->comm_path, $COMPOSE['id'], $attachment['id']); if ($part->content_id) $cid_map['cid:'.$part->content_id] = $url; else @@ -1066,7 +1095,8 @@ if (($part->content_id || $part->content_location) && $part->filename) { if ($attachment = rcmail_save_attachment($message, $pid)) { $COMPOSE['attachments'][$attachment['id']] = $attachment; - $url = $RCMAIL->comm_path.'&_action=display-attachment&_file=rcmfile'.$attachment['id'].'&_id='.$COMPOSE['id']; + $url = sprintf('%s&_id=%s&_action=display-attachment&_file=rcmfile%s', + $RCMAIL->comm_path, $COMPOSE['id'], $attachment['id']); if ($part->content_id) $cid_map['cid:'.$part->content_id] = $url; else @@ -1393,7 +1423,7 @@ $attrib['value'] = '1'; $checkbox = new html_checkbox($attrib); - if ($MESSAGE && in_array($compose_mode, array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT))) + if (in_array($compose_mode, array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT))) $mdn_default = (bool) $MESSAGE->headers->mdn_to; else $mdn_default = $RCMAIL->config->get('mdn_default'); @@ -1519,7 +1549,7 @@ } -function rcmail_adressbook_list($attrib = array()) +function rcmail_addressbook_list($attrib = array()) { global $RCMAIL, $OUTPUT; @@ -1548,7 +1578,7 @@ $js_id, (!empty($source['name']) ? Q($source['name']) : Q($id))); } - $OUTPUT->add_gui_object('adressbookslist', $attrib['id']); + $OUTPUT->add_gui_object('addressbookslist', $attrib['id']); return html::tag('ul', $attrib, $out, html::$common_attrib); } @@ -1584,7 +1614,7 @@ 'receiptcheckbox' => 'rcmail_receipt_checkbox', 'dsncheckbox' => 'rcmail_dsn_checkbox', 'storetarget' => 'rcmail_store_target_selection', - 'adressbooks' => 'rcmail_adressbook_list', + 'addressbooks' => 'rcmail_addressbook_list', 'addresslist' => 'rcmail_contacts_list', )); -- Gitblit v1.9.1