diff --git a/CHANGELOG b/CHANGELOG index 0b609317a..7a1661412 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,7 @@ CHANGELOG RoundCube Webmail - Allow absolute URLs to images in HTML messages/sigs (#1485666) - Fix message body which contains both inline attachments and emotions - Fix SQL query execution errors handling in rcube_mdb2 class (#1485509) +- Fix address names with '@' sign handling (#1485654) 2009/01/08 (alec) ---------- diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php index 36a346300..9fae0c672 100644 --- a/program/include/rcube_imap.php +++ b/program/include/rcube_imap.php @@ -2933,7 +2933,7 @@ class rcube_imap // remove any newlines and carriage returns before $a = $this->_explode_quoted_string('[,;]', preg_replace( "/[\r\n]/", " ", $str)); $result = array(); - + foreach ($a as $key => $val) { $val = preg_replace("/([\"\w]) $v) { - if (strpos($v, '@') > 0) - $result[$key]['address'] = str_replace('<', '', str_replace('>', '', $v)); + if (preg_match('/^<\S+@\S+>$/', $v)) + $result[$key]['address'] = trim($v, '<>'); else $result[$key]['name'] .= (empty($result[$key]['name'])?'':' ').str_replace("\"",'',stripslashes($v)); } diff --git a/program/steps/mail/sendmail.inc b/program/steps/mail/sendmail.inc index 5f12f3fe9..8edf15ffe 100644 --- a/program/steps/mail/sendmail.inc +++ b/program/steps/mail/sendmail.inc @@ -137,6 +137,40 @@ function rcmail_attach_emoticons(&$mime_message) return $body; } +// parse email address input +function rcmail_mailto_format($mailto) +{ + $regexp = array('/[,;]\s*[\r\n]+/', '/[\r\n]+/', '/[,;]\s*$/m', '/;/', '/(\S{1})(<\S+@\S+>)/U'); + $replace = array(', ', ', ', '', ',', '\\1 \\2'); + + // replace new lines and strip ending ', ', make address strings more valid also + $mailto = trim(preg_replace($regexp, $replace, $mailto)); + + $result = $name = ''; + + // handle simple email (without <>) + if (preg_match('/^\S+@\S+$/', $mailto)) + $result = '<' . $mailto . '>'; + else + // quote unquoted names (#1485654) + foreach (explode(' ', $mailto) as $item) { + if (preg_match('/<\S+@\S+>,*/', $item)) { + if ($name && ($name[0] != '"' || $name[strlen($name)-1] != '"') + && preg_match('/[\(\)\<\>\\\.\[\]@,;:"]/', $name)) { + $name = '"'.addcslashes($name, '"').'"'; + } + if ($name) { + $result .= ' ' . $name; + $name = ''; + } + $result .= ' ' . $item; + } else { + $name .= ($name ? ' ' : '') . $item; + } + } + + return trim($result); +} /****** compose message ********/ @@ -149,13 +183,9 @@ $message_id = sprintf('<%s@%s>', md5(uniqid('rcmail'.rand(),true)), $RCMAIL->con $input_charset = $OUTPUT->get_charset(); $message_charset = isset($_POST['_charset']) ? $_POST['_charset'] : $input_charset; -$mailto_regexp = array('/[,;]\s*[\r\n]+/', '/[\r\n]+/', '/[,;]\s*$/m', '/;/', '/(\S{1})(<\S+@\S+>)/U'); -$mailto_replace = array(', ', ', ', '', ',', '\\1 \\2'); - -// replace new lines and strip ending ', ', make address strings more valid also -$mailto = preg_replace($mailto_regexp, $mailto_replace, get_input_value('_to', RCUBE_INPUT_POST, TRUE, $message_charset)); -$mailcc = preg_replace($mailto_regexp, $mailto_replace, get_input_value('_cc', RCUBE_INPUT_POST, TRUE, $message_charset)); -$mailbcc = preg_replace($mailto_regexp, $mailto_replace, get_input_value('_bcc', RCUBE_INPUT_POST, TRUE, $message_charset)); +$mailto = rcmail_mailto_format(get_input_value('_to', RCUBE_INPUT_POST, TRUE, $message_charset)); +$mailcc = rcmail_mailto_format(get_input_value('_cc', RCUBE_INPUT_POST, TRUE, $message_charset)); +$mailbcc = rcmail_mailto_format(get_input_value('_bcc', RCUBE_INPUT_POST, TRUE, $message_charset)); if (empty($mailto) && !empty($mailcc)) { $mailto = $mailcc; @@ -196,7 +226,7 @@ if (!empty($identity_arr['organization'])) $headers['Organization'] = $identity_arr['organization']; if (!empty($_POST['_replyto'])) - $headers['Reply-To'] = preg_replace($mailto_regexp, $mailto_replace, get_input_value('_replyto', RCUBE_INPUT_POST, TRUE, $message_charset)); + $headers['Reply-To'] = rcmail_mailto_format(get_input_value('_replyto', RCUBE_INPUT_POST, TRUE, $message_charset)); else if (!empty($identity_arr['reply-to'])) $headers['Reply-To'] = $identity_arr['reply-to'];