From 0be9af45886c13f8821648ef9dfcaa62a132df40 Mon Sep 17 00:00:00 2001 From: tux-rampage Date: Tue, 28 Nov 2017 08:05:33 +0100 Subject: [PATCH 1/5] Add test case for CRLF messages with folded headers --- test/MessageTest.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/test/MessageTest.php b/test/MessageTest.php index 58b195b..abec205 100644 --- a/test/MessageTest.php +++ b/test/MessageTest.php @@ -10,6 +10,7 @@ namespace ZendTest\Mime; use Zend\Mime; +use Zend\Mime\Message; /** * @group Zend_Mime @@ -200,4 +201,25 @@ public function testDuplicatePartAddedWillThrowException() $message->addPart($part); $message->addPart($part); } + + public function testFromStringWithCrlfAndRfc2822FoldedHeaders() + { + // This is a fixture as provided by many mailservers + // e.g. cyrus or dovecot + $eol = "\r\n"; + $fixture = 'This is a MIME-encapsulated message' . $eol . $eol + . '--=_af4357ef34b786aae1491b0a2d14399f' . $eol + . 'Content-Type: text/plain' . $eol + . 'Content-Disposition: attachment;' . $eol + . "\t" . 'filename="test.txt"' . $eol // Valid folding + . $eol + . 'This is a test' . $eol + . '--=_af4357ef34b786aae1491b0a2d14399f--'; + + $message = Message::createFromMessage($fixture, '=_af4357ef34b786aae1491b0a2d14399f', $eol); + $parts = $message->getParts(); + + $this->assertEquals(1, count($parts)); + $this->assertEquals('attachment; filename="test.txt"', $parts[0]->getDisposition()); + } } From fd3a888b812c2944a826579aacab5af47518fe02 Mon Sep 17 00:00:00 2001 From: tux-rampage Date: Tue, 28 Nov 2017 08:07:01 +0100 Subject: [PATCH 2/5] Fix fromMessage failing on CRLF messages with folded headers --- src/Decode.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Decode.php b/src/Decode.php index b99d452..eb909aa 100644 --- a/src/Decode.php +++ b/src/Decode.php @@ -122,16 +122,23 @@ public static function splitMessage($message, &$headers, &$body, $EOL = Mime::LI } } + // TODO: splitMime replaces removes \r which breaks + // valid mime messages as returned by many mail servers + $headersEOL = $EOL; + // find an empty line between headers and body // default is set new line + // TODO: Maybe this is too much "magic", we should be more strict here if (strpos($message, $EOL . $EOL)) { list($headers, $body) = explode($EOL . $EOL, $message, 2); // next is the standard new line } elseif ($EOL != "\r\n" && strpos($message, "\r\n\r\n")) { list($headers, $body) = explode("\r\n\r\n", $message, 2); + $headersEOL = "\r\n"; // Headers::fromString will fail with incorrect eol // next is the other "standard" new line } elseif ($EOL != "\n" && strpos($message, "\n\n")) { list($headers, $body) = explode("\n\n", $message, 2); + $headersEOL = "\n"; // at last resort find anything that looks like a new line } else { ErrorHandler::start(E_NOTICE | E_WARNING); @@ -139,7 +146,7 @@ public static function splitMessage($message, &$headers, &$body, $EOL = Mime::LI ErrorHandler::stop(); } - $headers = Headers::fromString($headers, $EOL); + $headers = Headers::fromString($headers, $headersEOL); } /** From 45ce8d9cad9c009284af6a8c13f7a069c09758dc Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 28 Nov 2017 08:39:23 -0600 Subject: [PATCH 3/5] Updated comments to use `@todo` annotation Also updated to provide correct grammar, as well as formatting. --- src/Decode.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Decode.php b/src/Decode.php index eb909aa..bbff700 100644 --- a/src/Decode.php +++ b/src/Decode.php @@ -122,19 +122,19 @@ public static function splitMessage($message, &$headers, &$body, $EOL = Mime::LI } } - // TODO: splitMime replaces removes \r which breaks - // valid mime messages as returned by many mail servers + // @todo splitMime removes "\r" sequences, which breaks valid mime + // messages as returned by many mail servers $headersEOL = $EOL; // find an empty line between headers and body // default is set new line - // TODO: Maybe this is too much "magic", we should be more strict here + // @todo Maybe this is too much "magic"; we should be more strict here if (strpos($message, $EOL . $EOL)) { list($headers, $body) = explode($EOL . $EOL, $message, 2); // next is the standard new line } elseif ($EOL != "\r\n" && strpos($message, "\r\n\r\n")) { list($headers, $body) = explode("\r\n\r\n", $message, 2); - $headersEOL = "\r\n"; // Headers::fromString will fail with incorrect eol + $headersEOL = "\r\n"; // Headers::fromString will fail with incorrect EOL // next is the other "standard" new line } elseif ($EOL != "\n" && strpos($message, "\n\n")) { list($headers, $body) = explode("\n\n", $message, 2); From f800c7f9e18298ed09e5813ff8a27314a3c774a1 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 28 Nov 2017 08:40:15 -0600 Subject: [PATCH 4/5] Fixes indentation within test case --- test/MessageTest.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/MessageTest.php b/test/MessageTest.php index abec205..6072398 100644 --- a/test/MessageTest.php +++ b/test/MessageTest.php @@ -208,13 +208,13 @@ public function testFromStringWithCrlfAndRfc2822FoldedHeaders() // e.g. cyrus or dovecot $eol = "\r\n"; $fixture = 'This is a MIME-encapsulated message' . $eol . $eol - . '--=_af4357ef34b786aae1491b0a2d14399f' . $eol - . 'Content-Type: text/plain' . $eol - . 'Content-Disposition: attachment;' . $eol - . "\t" . 'filename="test.txt"' . $eol // Valid folding - . $eol - . 'This is a test' . $eol - . '--=_af4357ef34b786aae1491b0a2d14399f--'; + . '--=_af4357ef34b786aae1491b0a2d14399f' . $eol + . 'Content-Type: text/plain' . $eol + . 'Content-Disposition: attachment;' . $eol + . "\t" . 'filename="test.txt"' . $eol // Valid folding + . $eol + . 'This is a test' . $eol + . '--=_af4357ef34b786aae1491b0a2d14399f--'; $message = Message::createFromMessage($fixture, '=_af4357ef34b786aae1491b0a2d14399f', $eol); $parts = $message->getParts(); From 9aaf9791ec7c836b545aa32c00e466d3b8480e38 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 28 Nov 2017 08:41:50 -0600 Subject: [PATCH 5/5] Adds CHANGELOG entry for #30 --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65aded8..bfad0b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,9 @@ All notable changes to this project will be documented in this file, in reverse ### Fixed -- Nothing. +- [#30](https://github.com/zendframework/zend-mime/pull/30) fixes how EOL + characters are detected, to ensure that mail using `\r\n` as an EOL sequence + (including mail emitted by Cyrus and Dovecot) will be properly parsed. ## 2.6.1 - 2017-01-16