- Fix handling of comments inside an email address spec. (#1487673)
| | |
| | | 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) |
| | |
| | | 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); |
| | |
| | | |
| | | |
| | | /** |
| | | * 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 |
| | | */ |
| | |
| | | 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); |
| | | } |
| | | } |
| | | |