- Fix handling of comments inside an email address spec. (#1487673)

release-0.6
alecpl 14 years ago
parent bc374503bb
commit 6c68cbde37

@ -1,6 +1,7 @@
CHANGELOG Roundcube Webmail
===========================
- Fix handling of comments inside an email address spec. (#1487673)
- Fix randomly disappearing folders list in IE (#1487704)
- Fix list column add/removal in IE (#1487703)
- Fix login redirect issues (#1487686)

@ -4696,10 +4696,13 @@ class rcube_imap
private function _parse_address_list($str, $decode=true)
{
// remove any newlines and carriage returns before
$a = rcube_explode_quoted_string('[,;]', preg_replace( "/[\r\n]/", " ", $str));
$str = preg_replace('/\r?\n(\s|\t)?/', ' ', $str);
// extract list items, remove comments
$str = self::explode_header_string(',;', $str, true);
$result = array();
foreach ($a as $key => $val) {
foreach ($str as $key => $val) {
$name = '';
$address = '';
$val = trim($val);
@ -4740,6 +4743,81 @@ class rcube_imap
}
/**
* Explodes header (e.g. address-list) string into array of strings
* using specified separator characters with proper handling
* of quoted-strings and comments (RFC2822)
*
* @param string $separator String containing separator characters
* @param string $str Header string
* @param bool $remove_comments Enable to remove comments
*
* @return array Header items
*/
static function explode_header_string($separator, $str, $remove_comments=false)
{
$length = strlen($str);
$result = array();
$quoted = false;
$comment = 0;
$out = '';
for ($i=0; $i<$length; $i++) {
// we're inside a quoted string
if ($quoted) {
if ($str[$i] == '"') {
$quoted = false;
}
else if ($str[$i] == '\\') {
if ($comment <= 0) {
$out .= '\\';
}
$i++;
}
}
// we're inside a comment string
else if ($comment > 0) {
if ($str[$i] == ')') {
$comment--;
}
else if ($str[$i] == '(') {
$comment++;
}
else if ($str[$i] == '\\') {
$i++;
}
continue;
}
// separator, add to result array
else if (strpos($separator, $str[$i]) !== false) {
if ($out) {
$result[] = $out;
}
$out = '';
continue;
}
// start of quoted string
else if ($str[$i] == '"') {
$quoted = true;
}
// start of comment
else if ($remove_comments && $str[$i] == '(') {
$comment++;
}
if ($comment <= 0) {
$out .= $str[$i];
}
}
if ($out && $comment <= 0) {
$result[] = $out;
}
return $result;
}
/**
* This is our own debug handler for the IMAP connection
* @access public

@ -35,28 +35,45 @@ class rcube_test_maildecode extends UnitTestCase
8 => '"Test<Test" <test@domain.tld>',
9 => '=?ISO-8859-1?B?VGVzdAo=?= <test@domain.tld>',
10 => '=?ISO-8859-1?B?VGVzdAo=?=<test@domain.tld>', // #1487068
// comments in address (#1487673)
11 => 'Test (comment) <test@domain.tld>',
12 => '"Test" (comment) <test@domain.tld>',
13 => '"Test (comment)" (comment) <test@domain.tld>',
14 => '(comment) <test@domain.tld>',
15 => 'Test <test@(comment)domain.tld>',
16 => 'Test Test ((comment)) <test@domain.tld>',
17 => 'test@domain.tld (comment)',
18 => '"Test,Test" <test@domain.tld>',
);
$results = array(
0 => array('', 'test@domain.tld'),
1 => array('', 'test@domain.tld'),
2 => array('Test', 'test@domain.tld'),
3 => array('Test Test', 'test@domain.tld'),
4 => array('Test Test', 'test@domain.tld'),
5 => array('Test Test', 'test@domain.tld'),
6 => array('Test Test', 'test@domain.tld'),
7 => array('Test " Test', 'test@domain.tld'),
8 => array('Test<Test', 'test@domain.tld'),
9 => array('Test', 'test@domain.tld'),
10 => array('Test', 'test@domain.tld'),
0 => array(1, '', 'test@domain.tld'),
1 => array(1, '', 'test@domain.tld'),
2 => array(1, 'Test', 'test@domain.tld'),
3 => array(1, 'Test Test', 'test@domain.tld'),
4 => array(1, 'Test Test', 'test@domain.tld'),
5 => array(1, 'Test Test', 'test@domain.tld'),
6 => array(1, 'Test Test', 'test@domain.tld'),
7 => array(1, 'Test " Test', 'test@domain.tld'),
8 => array(1, 'Test<Test', 'test@domain.tld'),
9 => array(1, 'Test', 'test@domain.tld'),
10 => array(1, 'Test', 'test@domain.tld'),
11 => array(1, 'Test', 'test@domain.tld'),
12 => array(1, 'Test', 'test@domain.tld'),
13 => array(1, 'Test (comment)', 'test@domain.tld'),
14 => array(1, '', 'test@domain.tld'),
15 => array(1, 'Test', 'test@domain.tld'),
16 => array(1, 'Test Test', 'test@domain.tld'),
17 => array(1, '', 'test@domain.tld'),
18 => array(1, 'Test,Test', 'test@domain.tld'),
);
foreach ($headers as $idx => $header) {
$res = $this->app->imap->decode_address_list($header);
$this->assertEqual(1, count($res), "Rows number in result for header: " . $header);
$this->assertEqual($results[$idx][0], $res[1]['name'], "Name part decoding for header: " . $header);
$this->assertEqual($results[$idx][1], $res[1]['mailto'], "Name part decoding for header: " . $header);
$this->assertEqual($results[$idx][0], count($res), "Rows number in result for header: " . $header);
$this->assertEqual($results[$idx][1], $res[1]['name'], "Name part decoding for header: " . $header);
$this->assertEqual($results[$idx][2], $res[1]['mailto'], "Name part decoding for header: " . $header);
}
}

Loading…
Cancel
Save