- Fix multiple recipients input parsing (#1485733)

- added shared rcube_explode_quoted_string() function
release-0.6
alecpl 16 years ago
parent 33875df40b
commit 050410f560

@ -1,6 +1,10 @@
CHANGELOG RoundCube Webmail CHANGELOG RoundCube Webmail
--------------------------- ---------------------------
2009/02/13 (alec)
----------
- Fix multiple recipients input parsing (#1485733)
2009/02/10 (alec) 2009/02/10 (alec)
---------- ----------
- Use default_charset for messages without specified charset (#1485661, #1484961) - Use default_charset for messages without specified charset (#1485661, #1484961)

@ -1233,5 +1233,29 @@ class rcube_base_replacer
} }
} }
/**
* Explode quoted string
*
* @param string Delimiter expression string for preg_match()
* @param string Input string
*/
function rcube_explode_quoted_string($delimiter, $string)
{
$result = array();
$strlen = strlen($string);
for ($q=$p=$i=0; $i < $strlen; $i++) {
if ($string[$i] == "\"" && $string[$i-1] != "\\") {
$q = $q ? false : true;
}
else if (!$q && preg_match("/$delimiter/", $string[$i])) {
$result[] = substr($string, $p, $i - $p);
$p = $i + 1;
}
}
$result[] = substr($string, $p);
return $result;
}
?> ?>

@ -2958,13 +2958,13 @@ class rcube_imap
function _parse_address_list($str, $decode=true) function _parse_address_list($str, $decode=true)
{ {
// remove any newlines and carriage returns before // remove any newlines and carriage returns before
$a = $this->_explode_quoted_string('[,;]', preg_replace( "/[\r\n]/", " ", $str)); $a = rcube_explode_quoted_string('[,;]', preg_replace( "/[\r\n]/", " ", $str));
$result = array(); $result = array();
foreach ($a as $key => $val) foreach ($a as $key => $val)
{ {
$val = preg_replace("/([\"\w])</", "$1 <", $val); $val = preg_replace("/([\"\w])</", "$1 <", $val);
$sub_a = $this->_explode_quoted_string(' ', $decode ? $this->decode_header($val) : $val); $sub_a = rcube_explode_quoted_string(' ', $decode ? $this->decode_header($val) : $val);
$result[$key]['name'] = ''; $result[$key]['name'] = '';
foreach ($sub_a as $k => $v) foreach ($sub_a as $k => $v)
@ -2985,29 +2985,6 @@ class rcube_imap
return $result; return $result;
} }
/**
* @access private
*/
function _explode_quoted_string($delimiter, $string)
{
$result = array();
$strlen = strlen($string);
for ($q=$p=$i=0; $i < $strlen; $i++)
{
if ($string{$i} == "\"" && $string{$i-1} != "\\")
$q = $q ? false : true;
else if (!$q && preg_match("/$delimiter/", $string{$i}))
{
$result[] = substr($string, $p, $i - $p);
$p = $i + 1;
}
}
$result[] = substr($string, $p);
return $result;
}
} // end class rcube_imap } // end class rcube_imap

@ -128,7 +128,7 @@ class rcube_mail_mime extends Mail_mime
{ {
// if header contains e-mail addresses // if header contains e-mail addresses
if (preg_match('/\s<.+@[a-z0-9\-\.]+\.[a-z]+>/U', $hdr_value)) { if (preg_match('/\s<.+@[a-z0-9\-\.]+\.[a-z]+>/U', $hdr_value)) {
$chunks = $this->_explode_quoted_string(',', $hdr_value); $chunks = rcube_explode_quoted_string(',', $hdr_value);
} }
else { else {
$chunks = array($hdr_value); $chunks = array($hdr_value);
@ -187,24 +187,6 @@ class rcube_mail_mime extends Mail_mime
} }
function _explode_quoted_string($delimiter, $string)
{
$result = array();
$strlen = strlen($string);
for ($q=$p=$i=0; $i < $strlen; $i++) {
if ($string{$i} == "\"" && $string{$i-1} != "\\") {
$q = $q ? false : true;
}
else if (!$q && $string{$i} == $delimiter) {
$result[] = substr($string, $p, $i - $p);
$p = $i + 1;
}
}
$result[] = substr($string, $p);
return $result;
}
/** /**
* Provides caching of body of constructed MIME Message to avoid * Provides caching of body of constructed MIME Message to avoid
* duplicate construction of message and damage of MIME headers * duplicate construction of message and damage of MIME headers

@ -327,7 +327,7 @@ function smtp_parse_rfc822($recipients)
$recipients = implode(', ', $recipients); $recipients = implode(', ', $recipients);
$addresses = array(); $addresses = array();
$recipients = smtp_explode_quoted_str(",", $recipients); $recipients = rcube_explode_quoted_string(',', $recipients);
reset($recipients); reset($recipients);
while (list($k, $recipient) = each($recipients)) while (list($k, $recipient) = each($recipients))
@ -346,24 +346,4 @@ function smtp_parse_rfc822($recipients)
return $addresses; return $addresses;
} }
/**
* @access private
*/
function smtp_explode_quoted_str($delimiter, $string)
{
$quotes=explode("\"", $string);
while ( list($key, $val) = each($quotes))
if (($key % 2) == 1)
$quotes[$key] = str_replace($delimiter, "_!@!_", $quotes[$key]);
$string=implode("\"", $quotes);
$result=explode($delimiter, $string);
while (list($key, $val) = each($result))
$result[$key] = str_replace("_!@!_", $delimiter, $result[$key]);
return $result;
}
?> ?>

@ -143,33 +143,39 @@ function rcmail_mailto_format($mailto)
$regexp = array('/[,;]\s*[\r\n]+/', '/[\r\n]+/', '/[,;]\s*$/m', '/;/', '/(\S{1})(<\S+@\S+>)/U'); $regexp = array('/[,;]\s*[\r\n]+/', '/[\r\n]+/', '/[,;]\s*$/m', '/;/', '/(\S{1})(<\S+@\S+>)/U');
$replace = array(', ', ', ', '', ',', '\\1 \\2'); $replace = array(', ', ', ', '', ',', '\\1 \\2');
// replace new lines and strip ending ', ', make address strings more valid also // replace new lines and strip ending ', ', make address input more valid
$mailto = trim(preg_replace($regexp, $replace, $mailto)); $mailto = trim(preg_replace($regexp, $replace, $mailto));
$result = $name = ''; $result = array();
$items = rcube_explode_quoted_string(',', $mailto);
// handle simple email (without <>)
if (preg_match('/^\S+@\S+$/', $mailto)) foreach($items as $item) {
$result = '<' . $mailto . '>'; $item = trim($item);
else // address in brackets without name (do nothing)
// quote unquoted names (#1485654) if (preg_match('/^<\S+@\S+>$/', $item)) {
foreach (explode(' ', $mailto) as $item) { $result[] = $item;
if (preg_match('/<\S+@\S+>,*/', $item)) { // address without brackets and without name (add brackets)
if ($name && ($name[0] != '"' || $name[strlen($name)-1] != '"') } else if (preg_match('/^\S+@\S+$/', $item)) {
$result[] = '<'.$item.'>';
// address with name (handle name)
} else if (preg_match('/\S+@\S+>*$/', $item, $matches)) {
$address = $matches[0];
$name = str_replace($address, '', $item);
$name = trim($name);
if ($name && ($name[0] != '"' || $name[strlen($name)-1] != '"')
&& preg_match('/[\(\)\<\>\\\.\[\]@,;:"]/', $name)) { && preg_match('/[\(\)\<\>\\\.\[\]@,;:"]/', $name)) {
$name = '"'.addcslashes($name, '"').'"'; $name = '"'.addcslashes($name, '"').'"';
}
if ($name) {
$result .= ' ' . $name;
$name = '';
}
$result .= ' ' . $item;
} else {
$name .= ($name ? ' ' : '') . $item;
} }
if (!preg_match('/^<\S+@\S+>$/', $address))
$address = '<'.$address.'>';
$result[] = $name.' '.$address;
} else if (trim($item)) {
// @TODO: handle errors
} }
}
return trim($result); return implode(', ', $result);
} }
/****** compose message ********/ /****** compose message ********/

Loading…
Cancel
Save