Skip to content

Commit 63b88df

Browse files
committed
Merge pull request zendframework#44 from mleko/fix/special-chars
Inverse decode-split order, allow special char containing labels
2 parents 0dde51d + 91d0098 commit 63b88df

File tree

2 files changed

+61
-14
lines changed

2 files changed

+61
-14
lines changed

src/Header/AbstractAddressList.php

+27-14
Original file line numberDiff line numberDiff line change
@@ -42,31 +42,44 @@ abstract class AbstractAddressList implements HeaderInterface
4242
public static function fromString($headerLine)
4343
{
4444
list($fieldName, $fieldValue) = GenericHeader::splitHeaderLine($headerLine);
45-
$decodedValue = HeaderWrap::mimeDecodeValue($fieldValue);
46-
$wasEncoded = ($decodedValue !== $fieldValue);
47-
$fieldValue = $decodedValue;
48-
4945
if (strtolower($fieldName) !== static::$type) {
5046
throw new Exception\InvalidArgumentException(sprintf(
51-
'Invalid header line for "%s" string',
52-
__CLASS__
53-
));
54-
}
55-
$header = new static();
56-
if ($wasEncoded) {
57-
$header->setEncoding('UTF-8');
47+
'Invalid header line for "%s" string',
48+
__CLASS__
49+
));
5850
}
51+
5952
// split value on ","
6053
$fieldValue = str_replace(Headers::FOLDING, ' ', $fieldValue);
6154
$fieldValue = preg_replace('/[^:]+:([^;]*);/', '$1,', $fieldValue);
62-
$values = str_getcsv($fieldValue, ',');
55+
$values = str_getcsv($fieldValue, ',');
56+
57+
$wasEncoded = false;
6358
array_walk(
6459
$values,
65-
function (&$value) {
66-
$value = trim($value);
60+
function (&$value) use (&$wasEncoded) {
61+
$decodedValue = HeaderWrap::mimeDecodeValue($value);
62+
$wasEncoded = $wasEncoded || ($decodedValue !== $value);
63+
$value = trim($decodedValue);
6764
$value = self::stripComments($value);
65+
$value = preg_replace(
66+
[
67+
'#(?<!\\\)"(.*)(?<!\\\)"#', //quoted-text
68+
'#\\\([\x01-\x09\x0b\x0c\x0e-\x7f])#' //quoted-pair
69+
],
70+
[
71+
'\\1',
72+
'\\1'
73+
],
74+
$value
75+
);
6876
}
6977
);
78+
$header = new static();
79+
if ($wasEncoded) {
80+
$header->setEncoding('UTF-8');
81+
}
82+
7083
$values = array_filter($values);
7184

7285
$addressList = $header->getAddressList();

test/Header/AddressListHeaderTest.php

+34
Original file line numberDiff line numberDiff line change
@@ -210,4 +210,38 @@ public function getAddressListsWithGroup()
210210
211211
];
212212
}
213+
214+
public function specialCharHeaderProvider()
215+
{
216+
return [
217+
[
218+
"To: =?UTF-8?B?dGVzdCxsYWJlbA==?= <[email protected]>, [email protected]",
219+
['[email protected]' => 'test,label', '[email protected]' => null],
220+
'UTF-8'
221+
],
222+
[
223+
'To: "TEST\",QUOTE" <[email protected]>, [email protected]',
224+
['[email protected]' => 'TEST",QUOTE', '[email protected]' => null],
225+
'ASCII'
226+
]
227+
];
228+
}
229+
230+
/**
231+
* @dataProvider specialCharHeaderProvider
232+
*/
233+
public function testDeserializationFromSpecialCharString($headerLine, $expected, $encoding)
234+
{
235+
$header = To::fromString($headerLine);
236+
237+
$expectedTo = new To();
238+
$addressList = $expectedTo->getAddressList();
239+
$addressList->addMany($expected);
240+
$expectedTo->setEncoding($encoding);
241+
$this->assertEquals($expectedTo, $header);
242+
foreach ($expected as $k => $v) {
243+
$this->assertTrue($addressList->has($k));
244+
$this->assertEquals($addressList->get($k)->getName(), $v);
245+
}
246+
}
213247
}

0 commit comments

Comments
 (0)