summaryrefslogtreecommitdiff
path: root/program
diff options
context:
space:
mode:
authoralecpl <alec@alec.pl>2011-01-20 07:39:26 +0000
committeralecpl <alec@alec.pl>2011-01-20 07:39:26 +0000
commit6c68cbde375cd425ed98c037e2fa964aca552744 (patch)
tree2c3fa4fd97bee0a3b9facc64a01d240029d84cc1 /program
parentbc374503bba543bf62caa7f3dcf27b837cb929a0 (diff)
- Fix handling of comments inside an email address spec. (#1487673)
Diffstat (limited to 'program')
-rw-r--r--program/include/rcube_imap.php82
1 files changed, 80 insertions, 2 deletions
diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php
index fa7998338..cab232da4 100644
--- a/program/include/rcube_imap.php
+++ b/program/include/rcube_imap.php
@@ -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);
@@ -4741,6 +4744,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
*/