header lazy loading breaks header access
glensc opened this issue · 2 comments
glensc commented
take this example code, after calling $message->getHeaders()
to lazy-load the headers, the DKIM-Signature
header can not be retrieved:
<?php
require __DIR__.'/vendor/autoload.php';
use PHPUnit\Framework\TestCase;
use Zend\Mail\Storage;
$headerValue = "v=1; a=rsa-sha25; c=relaxed/simple; d=example.org; h=\r\n\tcontent-language:content-type:content-type:in-reply-to";
$headers = "DKIM-Signature: {$headerValue}";
$message = new Storage\Message(['headers' => $headers, 'content' => 'irrelevant']);
$h = $message->getHeaders();
// calling toString will lazy load all headers
// and break DKIM-Signature
$h->toString();
$x = $h->get('DKIM-Signature');
// not reached here
i've narrowed it down to iconv_mime_decode in Zend\Mail\Header\HeaderWrap::mimeDecodeValue
seems it strips \n
for no apparent reason, leaving \r
in place, thus breaking header continuation sequence (\r\n\t
) (less
is used to visually see \r
):
$ php71 -r 'var_dump(iconv_mime_decode($s="v=1; a=rsa-sha256; c=relaxed/simple; d=example.net; h=\r\n bb", ICONV_MIME_DECODE_CONTINUE_ON_ERROR, "UTF-8"));var_dump($s);'|less
string(58) "v=1; a=rsa-sha256; c=relaxed/simple; d=example.net; h=^M bb"
string(59) "v=1; a=rsa-sha256; c=relaxed/simple; d=example.net; h=
bb"
glensc commented
exception trace from mimeDecodeValue
method calls (maybe useful):
#0 zend-mail/src/Header/GenericHeader.php(36): Zend\Mail\Header\HeaderWrap::mimeDecodeValue('v=1; a=rsa-sha2...')
#1 zend-mail/src/Headers.php(482): Zend\Mail\Header\GenericHeader::fromString('DKIM-Signature:...')
#2 zend-mail/src/Headers.php(231): Zend\Mail\Headers->loadHeader('DKIM-Signature:...')
#3 zend-mail/src/Headers.php(115): Zend\Mail\Headers->addHeaderLine('DKIM-Signature:...')
#4 zend-mail/vendor/zendframework/zend-mime/src/Decode.php(142): Zend\Mail\Headers::fromString('DKIM-Signature:...', '\n')
#5 zend-mail/src/Storage/Part.php(112): Zend\Mime\Decode::splitMessage('DKIM-Signature:...', 'DKIM-Signature:...', NULL)
#6 zend-mail/src/Storage/Message.php(54): Zend\Mail\Storage\Part->__construct(Array)
#7 zend-mail/test1.php(10): Zend\Mail\Storage\Message->__construct(Array)
#8 {main}
#0 zend-mail/src/Header/GenericHeader.php(36): Zend\Mail\Header\HeaderWrap::mimeDecodeValue('v=1; a=rsa-sha2...')
#1 zend-mail/src/Headers.php(497): Zend\Mail\Header\GenericHeader::fromString('DKIM-Signature:...')
#2 zend-mail/src/Headers.php(398): Zend\Mail\Headers->lazyLoadHeader(0)
#3 zend-mail/src/Headers.php(425): Zend\Mail\Headers->current()
#4 zend-mail/test1.php(14): Zend\Mail\Headers->toString()
#5 {main}