]>
Commit | Line | Data |
---|---|---|
1 | commit a29b8fb3146e318ba3fd9a084859f2e39553c084 | |
2 | Author: Elan Ruusamäe <glen@delfi.ee> | |
3 | Date: Wed Feb 10 09:35:53 2016 +0200 | |
4 | ||
5 | test and fix for #64 | |
6 | ||
7 | backport for 2.4 | |
8 | ||
9 | Conflicts: | |
10 | src/Header/HeaderWrap.php | |
11 | ||
12 | diff --git a/src/Header/HeaderWrap.php b/src/Header/HeaderWrap.php | |
13 | index df532edc..e0be2f56 100644 | |
14 | --- a/src/Header/HeaderWrap.php | |
15 | +++ b/src/Header/HeaderWrap.php | |
16 | @@ -116,7 +116,21 @@ abstract class HeaderWrap | |
17 | */ | |
18 | public static function canBeEncoded($value) | |
19 | { | |
20 | - $encoded = iconv_mime_encode('x-test', $value, array('scheme' => 'Q')); | |
21 | + // avoid any wrapping by specifying line length long enough | |
22 | + // "test" -> 4 | |
23 | + // "x-test: =?ISO-8859-1?B?dGVzdA==?=" -> 33 | |
24 | + // 8 +2 +3 +3 -> 16 | |
25 | + $charset = 'UTF-8'; | |
26 | + $line_length = strlen($value) * 4 + strlen($charset) + 16; | |
27 | + | |
28 | + $preferences = array( | |
29 | + 'scheme' => 'Q', | |
30 | + 'input-charset' => $charset, | |
31 | + 'output-charset' => $charset, | |
32 | + 'line-length' => $line_length, | |
33 | + ); | |
34 | + | |
35 | + $encoded = iconv_mime_encode('x-test', $value, $preferences); | |
36 | ||
37 | return (false !== $encoded); | |
38 | } | |
39 | ||
40 | commit 755b22727a126608611b6a58c289ad6744db21a9 | |
41 | Merge: 6034313f 393b43c9 | |
42 | Author: Elan Ruusamäe <glen@delfi.ee> | |
43 | Date: Mon Feb 15 11:51:30 2016 +0200 | |
44 | ||
45 | Merge tag 'release-2.4.9' into develop-2.4 | |
46 | ||
47 | zend-mail 2.4.9 | |
48 | ||
49 | Conflicts: | |
50 | composer.json | |
51 | ||
52 | commit 222ace2631198f7498ae7c3799caaf6fc3a7936a | |
53 | Merge: 755b2272 c1c73d7f | |
54 | Author: Elan Ruusamäe <glen@delfi.ee> | |
55 | Date: Fri Jan 13 17:39:32 2017 +0200 | |
56 | ||
57 | Merge tag 'release-2.4.11' into develop-2.4 | |
58 | ||
59 | zend-mail 2.4.11 | |
60 | ||
61 | Added | |
62 | ----- | |
63 | ||
64 | - Nothing. | |
65 | ||
66 | Deprecated | |
67 | ---------- | |
68 | ||
69 | - Nothing. | |
70 | ||
71 | Removed | |
72 | ------- | |
73 | ||
74 | - Nothing. | |
75 | ||
76 | Fixed | |
77 | ----- | |
78 | ||
79 | - Fixes the [ZF2016-04 advisory](https://framework.zend.com/security/advisory/ZF2016-04) | |
80 | ("Potential remote code execution in zend-mail via Sendmail adapter"). | |
81 | ||
82 | commit 8493b2a0610c59fbeeaf0ffc44340810d4d84d93 | |
83 | Author: Etienne CHAMPETIER <etienne.champetier@fiducial.net> | |
84 | Date: Fri May 29 14:32:09 2015 +0200 | |
85 | ||
86 | Headers: fix bad sprintf call | |
87 | ||
88 | Signed-off-by: Etienne CHAMPETIER <etienne.champetier@fiducial.net> | |
89 | ||
90 | diff --git a/src/Headers.php b/src/Headers.php | |
91 | index 3ceb10be..b416f52a 100644 | |
92 | --- a/src/Headers.php | |
93 | +++ b/src/Headers.php | |
94 | @@ -220,6 +220,7 @@ class Headers implements Countable, Iterator | |
95 | if (!is_string($headerFieldNameOrLine)) { | |
96 | throw new Exception\InvalidArgumentException(sprintf( | |
97 | '%s expects its first argument to be a string; received "%s"', | |
98 | + __METHOD__, | |
99 | (is_object($headerFieldNameOrLine) | |
100 | ? get_class($headerFieldNameOrLine) | |
101 | : gettype($headerFieldNameOrLine)) | |
102 | ||
103 | commit 66eeb12567335f3a23aea7538a82e9a144464427 | |
104 | Author: Denis Sokolov <denis@sokolov.cc> | |
105 | Date: Wed Jun 10 16:44:27 2015 +0300 | |
106 | ||
107 | Handle simple comments in address lists | |
108 | ||
109 | diff --git a/src/Header/AbstractAddressList.php b/src/Header/AbstractAddressList.php | |
110 | index e7db7240..b13f9ebd 100644 | |
111 | --- a/src/Header/AbstractAddressList.php | |
112 | +++ b/src/Header/AbstractAddressList.php | |
113 | @@ -63,6 +63,7 @@ abstract class AbstractAddressList implements HeaderInterface | |
114 | $values, | |
115 | function (&$value) { | |
116 | $value = trim($value); | |
117 | + $value = self::stripComments($value); | |
118 | } | |
119 | ); | |
120 | ||
121 | @@ -155,4 +156,19 @@ abstract class AbstractAddressList implements HeaderInterface | |
122 | $value = $this->getFieldValue(HeaderInterface::FORMAT_ENCODED); | |
123 | return (empty($value)) ? '' : sprintf('%s: %s', $name, $value); | |
124 | } | |
125 | + | |
126 | + // Supposed to be private, protected as a workaround for PHP bug 68194 | |
127 | + protected static function stripComments($value) | |
128 | + { | |
129 | + return preg_replace( | |
130 | + '/\\( | |
131 | + ( | |
132 | + \\\\.| | |
133 | + [^\\\\)] | |
134 | + )+ | |
135 | + \\)/x', | |
136 | + '', | |
137 | + $value | |
138 | + ); | |
139 | + } | |
140 | } | |
141 | ||
142 | commit 5064f95148c1d996b5b25bc556830da9a8458e6a | |
143 | Author: Denis Sokolov <denis@sokolov.cc> | |
144 | Date: Thu Jun 11 13:27:04 2015 +0300 | |
145 | ||
146 | Handle groups in address lists | |
147 | ||
148 | diff --git a/src/Header/AbstractAddressList.php b/src/Header/AbstractAddressList.php | |
149 | index b13f9ebd..e0b4e78c 100644 | |
150 | --- a/src/Header/AbstractAddressList.php | |
151 | +++ b/src/Header/AbstractAddressList.php | |
152 | @@ -58,6 +58,7 @@ abstract class AbstractAddressList implements HeaderInterface | |
153 | } | |
154 | // split value on "," | |
155 | $fieldValue = str_replace(Headers::FOLDING, ' ', $fieldValue); | |
156 | + $fieldValue = preg_replace('/[^:]+:([^;]*);/', '$1,', $fieldValue); | |
157 | $values = str_getcsv($fieldValue, ','); | |
158 | array_walk( | |
159 | $values, | |
160 | @@ -66,6 +67,7 @@ abstract class AbstractAddressList implements HeaderInterface | |
161 | $value = self::stripComments($value); | |
162 | } | |
163 | ); | |
164 | + $values = array_filter($values); | |
165 | ||
166 | $addressList = $header->getAddressList(); | |
167 | foreach ($values as $address) { | |
168 | ||
169 | commit ebdc224fb6847c39e9691631eef23b3b1c3eb6a0 | |
170 | Author: Stefano Torresi <stefano@torresi.io> | |
171 | Date: Wed Jun 3 17:33:40 2015 +0200 | |
172 | ||
173 | fixes zendframework/zf2#7555 | |
174 | ||
175 | diff --git a/src/Header/Sender.php b/src/Header/Sender.php | |
176 | index 2efc23bf..e7bcac63 100644 | |
177 | --- a/src/Header/Sender.php | |
178 | +++ b/src/Header/Sender.php | |
179 | @@ -39,25 +39,23 @@ class Sender implements HeaderInterface | |
180 | ||
181 | // check to ensure proper header type for this factory | |
182 | if (strtolower($name) !== 'sender') { | |
183 | - throw new Exception\InvalidArgumentException('Invalid header line for Sender string'); | |
184 | + throw new Exception\InvalidArgumentException('Invalid header name for Sender string'); | |
185 | } | |
186 | ||
187 | - $header = new static(); | |
188 | - $senderName = ''; | |
189 | - $senderEmail = ''; | |
190 | + $header = new static(); | |
191 | + $hasMatches = preg_match('/^(?:(?P<name>.+)\s)?(?(name)<|<?)(?P<email>[^\s]+?)(?(name)>|>?)$/', $value, $matches); | |
192 | ||
193 | - // Check for address, and set if found | |
194 | - if (preg_match('/^(?P<name>.*?)<(?P<email>[^>]+)>$/', $value, $matches)) { | |
195 | - $senderName = trim($matches['name']); | |
196 | - if (empty($senderName)) { | |
197 | - $senderName = null; | |
198 | - } | |
199 | - $senderEmail = $matches['email']; | |
200 | - } else { | |
201 | - $senderEmail = $value; | |
202 | + if ($hasMatches !== 1) { | |
203 | + throw new Exception\InvalidArgumentException('Invalid header value for Sender string'); | |
204 | + } | |
205 | + | |
206 | + $senderName = trim($matches['name']); | |
207 | + | |
208 | + if (empty($senderName)) { | |
209 | + $senderName = null; | |
210 | } | |
211 | ||
212 | - $header->setAddress($senderEmail, $senderName); | |
213 | + $header->setAddress($matches['email'], $senderName); | |
214 | ||
215 | return $header; | |
216 | } | |
217 | ||
218 | commit c012507f8ae08eb92edb022c290d84dd9966fb46 | |
219 | Author: Stefano Torresi <stefano@torresi.io> | |
220 | Date: Mon Oct 26 20:26:11 2015 +0100 | |
221 | ||
222 | comment the regex | |
223 | ||
224 | diff --git a/src/Header/Sender.php b/src/Header/Sender.php | |
225 | index e7bcac63..9f532949 100644 | |
226 | --- a/src/Header/Sender.php | |
227 | +++ b/src/Header/Sender.php | |
228 | @@ -43,6 +43,12 @@ class Sender implements HeaderInterface | |
229 | } | |
230 | ||
231 | $header = new static(); | |
232 | + | |
233 | + /** | |
234 | + * matches the header value so that the email must be enclosed by < > when a name is present | |
235 | + * 'name' and 'email' capture groups correspond respectively to 'display-name' and 'addr-spec' in the ABNF | |
236 | + * @see https://tools.ietf.org/html/rfc5322#section-3.4 | |
237 | + */ | |
238 | $hasMatches = preg_match('/^(?:(?P<name>.+)\s)?(?(name)<|<?)(?P<email>[^\s]+?)(?(name)>|>?)$/', $value, $matches); | |
239 | ||
240 | if ($hasMatches !== 1) { | |
241 | ||
242 | commit bfe40077aeed5c2cf401d23d0508d63b5c44d8c6 | |
243 | Author: Elan Ruusamäe <glen@delfi.ee> | |
244 | Date: Sun Jan 31 00:03:58 2016 +0200 | |
245 | ||
246 | add format param to toArray | |
247 | ||
248 | this allows exporting headers in raw or encoded form | |
249 | ||
250 | diff --git a/src/Headers.php b/src/Headers.php | |
251 | index b416f52a..c05cde1b 100644 | |
252 | --- a/src/Headers.php | |
253 | +++ b/src/Headers.php | |
254 | @@ -430,10 +430,11 @@ class Headers implements Countable, Iterator | |
255 | /** | |
256 | * Return the headers container as an array | |
257 | * | |
258 | - * @todo determine how to produce single line headers, if they are supported | |
259 | + * @param bool $format Return the values in Mime::Encoded or in Raw format | |
260 | * @return array | |
261 | + * @todo determine how to produce single line headers, if they are supported | |
262 | */ | |
263 | - public function toArray() | |
264 | + public function toArray($format = Header\HeaderInterface::FORMAT_RAW) | |
265 | { | |
266 | $headers = array(); | |
267 | /* @var $header Header\HeaderInterface */ | |
268 | @@ -443,9 +444,9 @@ class Headers implements Countable, Iterator | |
269 | if (!isset($headers[$name])) { | |
270 | $headers[$name] = array(); | |
271 | } | |
272 | - $headers[$name][] = $header->getFieldValue(); | |
273 | + $headers[$name][] = $header->getFieldValue($format); | |
274 | } else { | |
275 | - $headers[$header->getFieldName()] = $header->getFieldValue(); | |
276 | + $headers[$header->getFieldName()] = $header->getFieldValue($format); | |
277 | } | |
278 | } | |
279 | return $headers; | |
280 | ||
281 | commit 8892c77410b08d2f0df90d4813904c10d741bd20 | |
282 | Author: Daniel Król <daniel@krol.me> | |
283 | Date: Wed Dec 2 17:24:47 2015 +0100 | |
284 | ||
285 | Inverse decode-split order, allow special char containing labels | |
286 | ||
287 | diff --git a/src/Header/AbstractAddressList.php b/src/Header/AbstractAddressList.php | |
288 | index e0b4e78c..64e5f8f9 100644 | |
289 | --- a/src/Header/AbstractAddressList.php | |
290 | +++ b/src/Header/AbstractAddressList.php | |
291 | @@ -42,31 +42,44 @@ abstract class AbstractAddressList implements HeaderInterface | |
292 | public static function fromString($headerLine) | |
293 | { | |
294 | list($fieldName, $fieldValue) = GenericHeader::splitHeaderLine($headerLine); | |
295 | - $decodedValue = HeaderWrap::mimeDecodeValue($fieldValue); | |
296 | - $wasEncoded = ($decodedValue !== $fieldValue); | |
297 | - $fieldValue = $decodedValue; | |
298 | - | |
299 | if (strtolower($fieldName) !== static::$type) { | |
300 | throw new Exception\InvalidArgumentException(sprintf( | |
301 | - 'Invalid header line for "%s" string', | |
302 | - __CLASS__ | |
303 | - )); | |
304 | - } | |
305 | - $header = new static(); | |
306 | - if ($wasEncoded) { | |
307 | - $header->setEncoding('UTF-8'); | |
308 | + 'Invalid header line for "%s" string', | |
309 | + __CLASS__ | |
310 | + )); | |
311 | } | |
312 | + | |
313 | // split value on "," | |
314 | $fieldValue = str_replace(Headers::FOLDING, ' ', $fieldValue); | |
315 | $fieldValue = preg_replace('/[^:]+:([^;]*);/', '$1,', $fieldValue); | |
316 | - $values = str_getcsv($fieldValue, ','); | |
317 | + $values = str_getcsv($fieldValue, ','); | |
318 | + | |
319 | + $wasEncoded = false; | |
320 | array_walk( | |
321 | $values, | |
322 | - function (&$value) { | |
323 | - $value = trim($value); | |
324 | + function (&$value) use (&$wasEncoded) { | |
325 | + $decodedValue = HeaderWrap::mimeDecodeValue($value); | |
326 | + $wasEncoded = $wasEncoded || ($decodedValue !== $value); | |
327 | + $value = trim($decodedValue); | |
328 | $value = self::stripComments($value); | |
329 | + $value = preg_replace( | |
330 | + [ | |
331 | + '#(?<!\\\)"(.*)(?<!\\\)"#', //quoted-text | |
332 | + '#\\\([\x01-\x09\x0b\x0c\x0e-\x7f])#' //quoted-pair | |
333 | + ], | |
334 | + [ | |
335 | + '\\1', | |
336 | + '\\1' | |
337 | + ], | |
338 | + $value | |
339 | + ); | |
340 | } | |
341 | ); | |
342 | + $header = new static(); | |
343 | + if ($wasEncoded) { | |
344 | + $header->setEncoding('UTF-8'); | |
345 | + } | |
346 | + | |
347 | $values = array_filter($values); | |
348 | ||
349 | $addressList = $header->getAddressList(); | |
350 | ||
351 | commit 9b54b914885a3c07fa7522fe1bedf7fb4482392b | |
352 | Author: Daniel Król <daniel@krol.me> | |
353 | Date: Wed Dec 2 17:01:45 2015 +0100 | |
354 | ||
355 | Use RFC compliant EOL to allow new lines in message body | |
356 | http://www.ietf.org/rfc/rfc2821.txt | |
357 | ||
358 | diff --git a/src/Message.php b/src/Message.php | |
359 | index e16c2438..f83c2961 100644 | |
360 | --- a/src/Message.php | |
361 | +++ b/src/Message.php | |
362 | @@ -551,7 +551,7 @@ class Message | |
363 | $message = new static(); | |
364 | $headers = null; | |
365 | $content = null; | |
366 | - Mime\Decode::splitMessage($rawMessage, $headers, $content); | |
367 | + Mime\Decode::splitMessage($rawMessage, $headers, $content, Headers::EOL); | |
368 | if ($headers->has('mime-version')) { | |
369 | // todo - restore body to mime\message | |
370 | } | |
371 | ||
372 | commit 788375fa8b156424a6b9afe40dac23ba6f00b916 | |
373 | Author: Marvin Feldmann <BreyndotEchse@users.noreply.github.com> | |
374 | Date: Fri Apr 15 16:53:17 2016 +0200 | |
375 | ||
376 | Allow DNS Hostnames | |
377 | ||
378 | diff --git a/src/Address.php b/src/Address.php | |
379 | index e97878d5..e4c89d20 100644 | |
380 | --- a/src/Address.php | |
381 | +++ b/src/Address.php | |
382 | @@ -27,7 +27,7 @@ class Address implements Address\AddressInterface | |
383 | */ | |
384 | public function __construct($email, $name = null) | |
385 | { | |
386 | - $emailAddressValidator = new EmailAddressValidator(Hostname::ALLOW_LOCAL); | |
387 | + $emailAddressValidator = new EmailAddressValidator(Hostname::ALLOW_DNS | Hostname::ALLOW_LOCAL); | |
388 | if (! is_string($email) || empty($email)) { | |
389 | throw new Exception\InvalidArgumentException('Email must be a valid email address'); | |
390 | } | |
391 | ||
392 | commit e37c5e15185143eaaff7f2c4c2a64f605926c978 | |
393 | Author: Marvin Feldmann <BreyndotEchse@users.noreply.github.com> | |
394 | Date: Tue Apr 19 16:24:38 2016 +0200 | |
395 | ||
396 | Return email address(es) with ACE | |
397 | ||
398 | diff --git a/src/Header/AbstractAddressList.php b/src/Header/AbstractAddressList.php | |
399 | index 64e5f8f9..db40486a 100644 | |
400 | --- a/src/Header/AbstractAddressList.php | |
401 | +++ b/src/Header/AbstractAddressList.php | |
402 | @@ -94,6 +94,19 @@ abstract class AbstractAddressList implements HeaderInterface | |
403 | return $this->fieldName; | |
404 | } | |
405 | ||
406 | + /** | |
407 | + * Safely convert UTF-8 encoded domain name to ASCII | |
408 | + * @param string $domainName the UTF-8 encoded email | |
409 | + * @return string | |
410 | + */ | |
411 | + protected function idnToAscii($domainName) | |
412 | + { | |
413 | + if (extension_loaded('intl')) { | |
414 | + return (idn_to_ascii($domainName) ?: $domainName); | |
415 | + } | |
416 | + return $domainName; | |
417 | + } | |
418 | + | |
419 | public function getFieldValue($format = HeaderInterface::FORMAT_RAW) | |
420 | { | |
421 | $emails = array(); | |
422 | @@ -103,22 +116,29 @@ abstract class AbstractAddressList implements HeaderInterface | |
423 | $email = $address->getEmail(); | |
424 | $name = $address->getName(); | |
425 | ||
426 | - if (empty($name)) { | |
427 | - $emails[] = $email; | |
428 | - continue; | |
429 | - } | |
430 | - | |
431 | - if (false !== strstr($name, ',')) { | |
432 | + if (!empty($name) && false !== strstr($name, ',')) { | |
433 | $name = sprintf('"%s"', $name); | |
434 | } | |
435 | ||
436 | if ($format === HeaderInterface::FORMAT_ENCODED | |
437 | && 'ASCII' !== $encoding | |
438 | ) { | |
439 | - $name = HeaderWrap::mimeEncodeValue($name, $encoding); | |
440 | + if (!empty($name)) { | |
441 | + $name = HeaderWrap::mimeEncodeValue($name, $encoding); | |
442 | + } | |
443 | + | |
444 | + if (preg_match('/^(.+)@([^@]+)$/', $email, $matches)) { | |
445 | + $localPart = $matches[1]; | |
446 | + $hostname = $this->idnToAscii($matches[2]); | |
447 | + $email = sprintf('%s@%s', $localPart, $hostname); | |
448 | + } | |
449 | } | |
450 | ||
451 | - $emails[] = sprintf('%s <%s>', $name, $email); | |
452 | + if (empty($name)) { | |
453 | + $emails[] = $email; | |
454 | + } else { | |
455 | + $emails[] = sprintf('%s <%s>', $name, $email); | |
456 | + } | |
457 | } | |
458 | ||
459 | // Ensure the values are valid before sending them. | |
460 | ||
461 | commit 6bbdb6b5b8f549fa9f87cc5a6adbb558dfefeb99 | |
462 | Merge: 786a1418 e00ac010 | |
463 | Author: Elan Ruusamäe <glen@delfi.ee> | |
464 | Date: Sun May 14 15:16:24 2017 +0300 | |
465 | ||
466 | Merge branch 'fix-129' into develop-2.4 | |
467 | ||
468 | fixing: | |
469 | https://github.com/zendframework/zend-mail/issues/129 | |
470 | ||
471 | commit ddf2e8ec39394774e753b9a44793e845134a3524 | |
472 | Author: Matthew Weier O'Phinney <matthew@zend.com> | |
473 | Date: Thu May 5 12:56:11 2016 -0500 | |
474 | ||
475 | Merge branch 'hotfix/86' | |
476 | ||
477 | Close #86 | |
478 | ||
479 | diff --git a/src/Headers.php b/src/Headers.php | |
480 | index c05cde1b..eac2bf9f 100644 | |
481 | --- a/src/Headers.php | |
482 | +++ b/src/Headers.php | |
483 | @@ -228,7 +228,11 @@ class Headers implements Countable, Iterator | |
484 | } | |
485 | ||
486 | if ($fieldValue === null) { | |
487 | - $this->addHeader(Header\GenericHeader::fromString($headerFieldNameOrLine)); | |
488 | + $headers = $this->loadHeader($headerFieldNameOrLine); | |
489 | + $headers = is_array($headers) ? $headers : [$headers]; | |
490 | + foreach ($headers as $header) { | |
491 | + $this->addHeader($header); | |
492 | + } | |
493 | } elseif (is_array($fieldValue)) { | |
494 | foreach ($fieldValue as $i) { | |
495 | $this->addHeader(Header\GenericMultiHeader::fromString($headerFieldNameOrLine . ':' . $i)); | |
496 | @@ -465,6 +469,19 @@ class Headers implements Countable, Iterator | |
497 | return true; | |
498 | } | |
499 | ||
500 | + /** | |
501 | + * Create Header object from header line | |
502 | + * | |
503 | + * @param string $headerLine | |
504 | + * @return Header\HeaderInterface|Header\HeaderInterface[] | |
505 | + */ | |
506 | + public function loadHeader($headerLine) | |
507 | + { | |
508 | + list($name, ) = Header\GenericHeader::splitHeaderLine($headerLine); | |
509 | + $class = $this->getPluginClassLoader()->load($name) ?: Header\GenericHeader::class; | |
510 | + return $class::fromString($headerLine); | |
511 | + } | |
512 | + | |
513 | /** | |
514 | * @param $index | |
515 | * @return mixed | |
516 | ||
517 | commit c3ac503689ffd00ac51e43c97c311e8753ecd32c | |
518 | Author: Elan Ruusamäe <glen@delfi.ee> | |
519 | Date: Tue Jun 13 00:54:18 2017 +0300 | |
520 | ||
521 | fix MessageId having double brackets | |
522 | ||
523 | this got broken from pull/86 when header lazyloading was omitted | |
524 | ||
525 | diff --git a/src/Header/MessageId.php b/src/Header/MessageId.php | |
526 | index 850757ea..03c52a75 100644 | |
527 | --- a/src/Header/MessageId.php | |
528 | +++ b/src/Header/MessageId.php | |
529 | @@ -27,7 +27,7 @@ class MessageId implements HeaderInterface | |
530 | } | |
531 | ||
532 | $header = new static(); | |
533 | - $header->setId($value); | |
534 | + $header->setId(trim($value, '<>')); | |
535 | ||
536 | return $header; | |
537 | } | |
538 | ||
539 | commit 63ac228e6f883ed8e26a7b8a02130348e2332edf | |
540 | Author: Elan Ruusamäe <glen@delfi.ee> | |
541 | Date: Wed Jun 28 00:19:11 2017 +0300 | |
542 | ||
543 | skip lazy-load for array as well | |
544 | ||
545 | refs: | |
546 | - a4a93ef0 | |
547 | - ddf2e8ec | |
548 | ||
549 | this should be sent upstream, but upstream doesn't seem to respond even | |
550 | to trivial pull-requests. | |
551 | ||
552 | diff --git a/src/Headers.php b/src/Headers.php | |
553 | index eac2bf9f..d4f9a9e7 100644 | |
554 | --- a/src/Headers.php | |
555 | +++ b/src/Headers.php | |
556 | @@ -207,9 +207,6 @@ class Headers implements Countable, Iterator | |
557 | /** | |
558 | * Add a raw header line, either in name => value, or as a single string 'name: value' | |
559 | * | |
560 | - * This method allows for lazy-loading in that the parsing and instantiation of HeaderInterface object | |
561 | - * will be delayed until they are retrieved by either get() or current() | |
562 | - * | |
563 | * @throws Exception\InvalidArgumentException | |
564 | * @param string $headerFieldNameOrLine | |
565 | * @param string $fieldValue optional | |
566 | @@ -238,7 +235,9 @@ class Headers implements Countable, Iterator | |
567 | $this->addHeader(Header\GenericMultiHeader::fromString($headerFieldNameOrLine . ':' . $i)); | |
568 | } | |
569 | } else { | |
570 | - $this->addHeader(Header\GenericHeader::fromString($headerFieldNameOrLine . ':' . $fieldValue)); | |
571 | + $class = $this->getPluginClassLoader()->load($headerFieldNameOrLine) ?: Header\GenericHeader::class; | |
572 | + $header = $class::fromString($headerFieldNameOrLine . ':' . $fieldValue); | |
573 | + $this->addHeader($header); | |
574 | } | |
575 | ||
576 | return $this; | |
577 | ||
578 | commit a95c496b4ec67953970ba366eefd29ba55ad1988 | |
579 | Author: Elan Ruusamäe <glen@delfi.ee> | |
580 | Date: Tue Jun 13 00:54:18 2017 +0300 | |
581 | ||
582 | update pull/156 to trim in setId, not in constructor | |
583 | ||
584 | otherwise it could get broken from other code paths as well | |
585 | ||
586 | diff --git a/src/Header/MessageId.php b/src/Header/MessageId.php | |
587 | index 03c52a75..e1bf2ff4 100644 | |
588 | --- a/src/Header/MessageId.php | |
589 | +++ b/src/Header/MessageId.php | |
590 | @@ -27,7 +27,7 @@ class MessageId implements HeaderInterface | |
591 | } | |
592 | ||
593 | $header = new static(); | |
594 | - $header->setId(trim($value, '<>')); | |
595 | + $header->setId($value); | |
596 | ||
597 | return $header; | |
598 | } | |
599 | @@ -68,6 +68,8 @@ class MessageId implements HeaderInterface | |
600 | { | |
601 | if ($id === null) { | |
602 | $id = $this->createMessageId(); | |
603 | + } else { | |
604 | + $id = trim($id, '<>'); | |
605 | } | |
606 | ||
607 | if (! HeaderValue::isValid($id) | |
608 | ||
609 | commit 24aeac0f3d866e64fcb20320b677b49d30fce185 | |
610 | Author: Elan Ruusamäe <glen@delfi.ee> | |
611 | Date: Thu Dec 28 23:00:28 2017 +0200 | |
612 | ||
613 | unfold before calling iconv_mime_decode | |
614 | ||
615 | diff --git a/src/Header/HeaderWrap.php b/src/Header/HeaderWrap.php | |
616 | index e0be2f56..674b4f64 100644 | |
617 | --- a/src/Header/HeaderWrap.php | |
618 | +++ b/src/Header/HeaderWrap.php | |
619 | @@ -103,6 +103,13 @@ abstract class HeaderWrap | |
620 | */ | |
621 | public static function mimeDecodeValue($value) | |
622 | { | |
623 | + // unfold first, because iconv_mime_decode is discarding "\n" with no apparent reason | |
624 | + // making the resulting value no longer valid. | |
625 | + | |
626 | + // see https://tools.ietf.org/html/rfc2822#section-2.2.3 about unfolding | |
627 | + $parts = explode(Headers::FOLDING, $value); | |
628 | + $value = implode(' ', $parts); | |
629 | + | |
630 | $decodedValue = iconv_mime_decode($value, ICONV_MIME_DECODE_CONTINUE_ON_ERROR, 'UTF-8'); | |
631 | ||
632 | return $decodedValue; | |
633 | ||
634 | commit 8bde8f75ccb1b28ec81248379bc6aa222fd24d7d | |
635 | Author: Elan Ruusamäe <glen@delfi.ee> | |
636 | Date: Wed Jan 31 10:57:53 2018 +0200 | |
637 | ||
638 | format exception message properly | |
639 | ||
640 | diff --git a/src/Headers.php b/src/Headers.php | |
641 | index d4f9a9e7..4b2c0b9c 100644 | |
642 | --- a/src/Headers.php | |
643 | +++ b/src/Headers.php | |
644 | @@ -107,7 +107,7 @@ class Headers implements Countable, Iterator | |
645 | ||
646 | // Line does not match header format! | |
647 | throw new Exception\RuntimeException(sprintf( | |
648 | - 'Line "%s"does not match header format!', | |
649 | + 'Line "%s" does not match header format!', | |
650 | $line | |
651 | )); | |
652 | } |