Fix incorrectly encoded address fields.

Address fields cannot contain : or " it causes a number of
mail servers/clients to be confused.

Fixes #4058
This commit is contained in:
mark_story 2013-09-12 20:14:11 -04:00
parent ba016c2c68
commit ba4afcc074
2 changed files with 31 additions and 3 deletions

View file

@ -762,6 +762,10 @@ class CakeEmail {
/**
* Format addresses
*
* If the address contains non alphanumeric/whitespace characters, it will
* be quoted as characters like `:` and `,` are known to cause issues
* in address header fields.
*
* @param array $address
* @return array
*/
@ -771,10 +775,11 @@ class CakeEmail {
if ($email === $alias) {
$return[] = $email;
} else {
if (strpos($alias, ',') !== false) {
$alias = '"' . $alias . '"';
$encoded = $this->_encode($alias);
if ($encoded === $alias && preg_match('/[^a-z0-9 ]/i', $encoded)) {
$encoded = '"' . str_replace('"', '\"', $encoded) . '"';
}
$return[] = sprintf('%s <%s>', $this->_encode($alias), $email);
$return[] = sprintf('%s <%s>', $encoded, $email);
}
}
return $return;

View file

@ -178,6 +178,25 @@ class CakeEmailTest extends CakeTestCase {
$result = $this->CakeEmail->from(array('cake@cakephp.org' => 'CakePHP', 'fail@cakephp.org' => 'From can only be one address'));
}
/**
* Test that from addresses using colons work.
*
* @return void
*/
public function testFromWithColonsAndQuotes() {
$address = array(
'info@example.com' => '70:20:00 " Forum'
);
$this->CakeEmail->from($address);
$this->assertEquals($address, $this->CakeEmail->from());
$this->CakeEmail->to('info@example.com')
->subject('Test email')
->transport('Debug');
$result = $this->CakeEmail->send();
$this->assertContains('From: "70:20:00 \" Forum" <info@example.com>', $result['headers']);
}
/**
* testSender method
*
@ -371,6 +390,10 @@ class CakeEmailTest extends CakeTestCase {
$expected = array('"Last, First" <me@example.com>');
$this->assertSame($expected, $result);
$result = $this->CakeEmail->formatAddress(array('me@example.com' => '"Last" First'));
$expected = array('"\"Last\" First" <me@example.com>');
$this->assertSame($expected, $result);
$result = $this->CakeEmail->formatAddress(array('me@example.com' => 'Last First'));
$expected = array('Last First <me@example.com>');
$this->assertSame($expected, $result);