diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d4235e9..ac1bf0e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ All notable changes to this project will be documented in this file, in reverse - [#213](https://github.com/zendframework/zend-mail/pull/213) re-adds support for PHP 5.6 and 7.0; ZF policy is never to bump the major version of a PHP requirement unless the package is bumping major version. +### Changed + +- Nothing. + ### Deprecated - Nothing. @@ -19,7 +23,8 @@ All notable changes to this project will be documented in this file, in reverse ### Fixed -- Nothing. +- [#147](https://github.com/zendframework/zend-mail/pull/147) fixes how address lists are parsed, expanding the functionality to allow either + `,` or `;` delimiters (or both in combination). ## 2.9.0 - 2017-03-01 diff --git a/src/AddressList.php b/src/AddressList.php index 36116c0f..2d6a13ad 100644 --- a/src/AddressList.php +++ b/src/AddressList.php @@ -31,7 +31,9 @@ public function add($emailOrAddress, $name = null) { if (is_string($emailOrAddress)) { $emailOrAddress = $this->createAddress($emailOrAddress, $name); - } elseif (! $emailOrAddress instanceof Address\AddressInterface) { + } + + if (! $emailOrAddress instanceof Address\AddressInterface) { throw new Exception\InvalidArgumentException(sprintf( '%s expects an email address or %s\Address object as its first argument; received "%s"', __METHOD__, @@ -65,14 +67,17 @@ public function addMany(array $addresses) foreach ($addresses as $key => $value) { if (is_int($key) || is_numeric($key)) { $this->add($value); - } elseif (is_string($key)) { - $this->add($key, $value); - } else { + continue; + } + + if (! is_string($key)) { throw new Exception\RuntimeException(sprintf( 'Invalid key type in provided addresses array ("%s")', (is_object($key) ? get_class($key) : var_export($key, 1)) )); } + + $this->add($key, $value); } return $this; } diff --git a/src/Header/AbstractAddressList.php b/src/Header/AbstractAddressList.php index a296c45d..1ac31595 100644 --- a/src/Header/AbstractAddressList.php +++ b/src/Header/AbstractAddressList.php @@ -50,7 +50,7 @@ public static function fromString($headerLine) // split value on "," $fieldValue = str_replace(Headers::FOLDING, ' ', $fieldValue); $fieldValue = preg_replace('/[^:]+:([^;]*);/', '$1,', $fieldValue); - $values = str_getcsv($fieldValue, ','); + $values = AddressListParser::parse($fieldValue); $wasEncoded = false; array_walk( @@ -80,6 +80,7 @@ function (&$value) use (&$wasEncoded) { $values = array_filter($values); + /** @var AddressList $addressList */ $addressList = $header->getAddressList(); foreach ($values as $address) { $addressList->addFromString($address); diff --git a/src/Header/AddressListParser.php b/src/Header/AddressListParser.php new file mode 100644 index 00000000..cb6141b0 --- /dev/null +++ b/src/Header/AddressListParser.php @@ -0,0 +1,86 @@ +list->get('zf-devteam@zend.com'); $this->assertNull($address->getName()); } + + /** + * Microsoft Outlook sends emails with semicolon separated To addresses. + * + * @see https://blogs.msdn.microsoft.com/oldnewthing/20150119-00/?p=44883 + */ + public function testSemicolonSeparator() + { + $header = 'Some User ; uzer2.surname@example.org;' + . ' asda.fasd@example.net, root@example.org'; + + // In previous versions, this throws: 'The input exceeds the allowed + // length'; hence the try/catch block, to allow finding the root cause. + try { + $to = Header\To::fromString('To:' . $header); + } catch (InvalidArgumentException $e) { + $this->fail('Header\To::fromString should not throw'); + } + $addressList = $to->getAddressList(); + + $this->assertEquals('Some User', $addressList->get('some.user@example.com')->getName()); + $this->assertTrue($addressList->has('uzer2.surname@example.org')); + $this->assertTrue($addressList->has('asda.fasd@example.net')); + $this->assertTrue($addressList->has('root@example.org')); + } }