From 983100e72ae04f04cce759bd9566e4857ac5b14d Mon Sep 17 00:00:00 2001 From: Pierre-Gildas MILLON <715479+pgmillon@users.noreply.github.com> Date: Mon, 4 Apr 2022 18:11:58 +0200 Subject: [PATCH 1/2] fix: binary files as part are corrupted when stripping carriage returns Signed-off-by: Pierre-Gildas MILLON <715479+pgmillon@users.noreply.github.com> --- src/Decode.php | 23 +++++++++-------------- test/MimeTest.php | 14 +++++++------- test/PartTest.php | 16 ++++++++++++++++ test/TestAsset/laminas.png | Bin 0 -> 13711 bytes 4 files changed, 32 insertions(+), 21 deletions(-) create mode 100644 test/TestAsset/laminas.png diff --git a/src/Decode.php b/src/Decode.php index 5afdeab..99656ae 100644 --- a/src/Decode.php +++ b/src/Decode.php @@ -22,6 +22,7 @@ use const E_NOTICE; use const E_WARNING; use const ICONV_MIME_DECODE_CONTINUE_ON_ERROR; +use const PREG_OFFSET_CAPTURE; class Decode { @@ -37,36 +38,30 @@ class Decode */ public static function splitMime($body, $boundary) { - // TODO: we're ignoring \r for now - is this function fast enough and is it safe to assume noone needs \r? - $body = str_replace("\r", '', $body); - - $start = 0; - $res = []; + $res = []; // find every mime part limiter and cut out the // string before it. // the part before the first boundary string is discarded: - $p = strpos($body, '--' . $boundary . "\n", $start); - if ($p === false) { + if (preg_match('/--' . $boundary . '\r?\n/', $body, $matches, PREG_OFFSET_CAPTURE) === 0) { // no parts found! return []; } // position after first boundary line - $start = $p + 3 + strlen($boundary); + $start = $matches[0][1] + strlen($matches[0][0]); - while (($p = strpos($body, '--' . $boundary . "\n", $start)) !== false) { - $res[] = substr($body, $start, $p - $start); - $start = $p + 3 + strlen($boundary); + while (preg_match('/--' . $boundary . '\r?\n/', $body, $matches, PREG_OFFSET_CAPTURE, $start) === 1) { + $res[] = substr($body, $start, $matches[0][1] - $start - 1); + $start = $matches[0][1] + strlen($matches[0][0]); } // no more parts, find end boundary - $p = strpos($body, '--' . $boundary . '--', $start); - if ($p === false) { + if (preg_match('/--' . $boundary . '--/', $body, $matches, PREG_OFFSET_CAPTURE, $start) !== 1) { throw new Exception\RuntimeException('Not a valid Mime Message: End Missing'); } // the remaining part also needs to be parsed: - $res[] = substr($body, $start, $p - $start); + $res[] = substr($body, $start, $matches[0][1] - $start - 1); return $res; } diff --git a/test/MimeTest.php b/test/MimeTest.php index 45e2be8..2e43ded 100644 --- a/test/MimeTest.php +++ b/test/MimeTest.php @@ -246,7 +246,7 @@ public static function dataTestFromMessageDecode(): array 'Alle meine Entchen schwimmen in dem See, schwimmen in dem See, K=C3=B6pfche= n in das Wasser, Schw=C3=A4nzchen in die H=C3=B6h!', ], - ['foobar', 'base64', 'Zm9vYmFyCg=='], + ['foobar', 'base64', 'Zm9vYmFy'], ]; // phpcs:enable } @@ -257,15 +257,15 @@ public static function dataTestFromMessageDecode(): array public function testFromMessageDecode(string $input, string $encoding, string $result): void { $parts = Mime\Message::createFromMessage( - '--089e0141a1902f83ee04e0a07b7a' . "\r\n" - . 'Content-Type: text/plain; charset=UTF-8' . "\r\n" - . 'Content-Transfer-Encoding: ' . $encoding . "\r\n" - . "\r\n" - . $result . "\r\n" + '--089e0141a1902f83ee04e0a07b7a' . "\n" + . 'Content-Type: text/plain; charset=UTF-8' . "\n" + . 'Content-Transfer-Encoding: ' . $encoding . "\n" + . "\n" + . $result . "\n" . '--089e0141a1902f83ee04e0a07b7a--', '089e0141a1902f83ee04e0a07b7a' )->getParts(); - $this->assertSame($input . "\n", $parts[0]->getRawContent()); + $this->assertSame($input, $parts[0]->getRawContent()); } /** diff --git a/test/PartTest.php b/test/PartTest.php index 0d25b9e..d62ad84 100644 --- a/test/PartTest.php +++ b/test/PartTest.php @@ -205,4 +205,20 @@ public function testSetContentRaisesInvalidArgumentExceptionForInvalidContentTyp $this->expectException(Mime\Exception\InvalidArgumentException::class); $part->setContent($content); } + + public function testBinaryPart() + { + $content = file_get_contents(__DIR__ . '/TestAsset/laminas.png'); + $inputMessage = new Mime\Message(); + $inputMessage->addPart(new Mime\Part('Hello World')); + $inputMessage->addPart(new Mime\Part($content)); + + $outputMessage = Mime\Message::createFromMessage( + $inputMessage->generateMessage(), + $inputMessage->getMime()->boundary() + ); + $parts = $outputMessage->getParts(); + $this->assertCount(2, $parts); + $this->assertEquals($content, $parts[1]->getContent()); + } } diff --git a/test/TestAsset/laminas.png b/test/TestAsset/laminas.png new file mode 100644 index 0000000000000000000000000000000000000000..b41e426cafa9c59cd5543930be75bb3fb4ed221c GIT binary patch literal 13711 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 literal 0 HcmV?d00001 From bb2566297360ac73f6554012e2be2e4faab8c61d Mon Sep 17 00:00:00 2001 From: Pierre-Gildas MILLON <715479+pgmillon@users.noreply.github.com> Date: Mon, 4 Apr 2022 21:04:26 +0200 Subject: [PATCH 2/2] fix: split parts according to sender EOL character Signed-off-by: Pierre-Gildas MILLON <715479+pgmillon@users.noreply.github.com> --- src/Decode.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Decode.php b/src/Decode.php index 99656ae..f95be42 100644 --- a/src/Decode.php +++ b/src/Decode.php @@ -42,16 +42,17 @@ public static function splitMime($body, $boundary) // find every mime part limiter and cut out the // string before it. // the part before the first boundary string is discarded: - if (preg_match('/--' . $boundary . '\r?\n/', $body, $matches, PREG_OFFSET_CAPTURE) === 0) { + if (preg_match('/--' . $boundary . '(\r?\n)/', $body, $matches, PREG_OFFSET_CAPTURE) === 0) { // no parts found! return []; } // position after first boundary line - $start = $matches[0][1] + strlen($matches[0][0]); + $start = $matches[0][1] + strlen($matches[0][0]); + $serverEOL = $matches[1][0]; while (preg_match('/--' . $boundary . '\r?\n/', $body, $matches, PREG_OFFSET_CAPTURE, $start) === 1) { - $res[] = substr($body, $start, $matches[0][1] - $start - 1); + $res[] = substr($body, $start, $matches[0][1] - $start - strlen($serverEOL)); $start = $matches[0][1] + strlen($matches[0][0]); } @@ -61,7 +62,7 @@ public static function splitMime($body, $boundary) } // the remaining part also needs to be parsed: - $res[] = substr($body, $start, $matches[0][1] - $start - 1); + $res[] = substr($body, $start, $matches[0][1] - $start - strlen($serverEOL)); return $res; }