Skip to content

Commit 0a9b263

Browse files
committed
Boundary parsing fixed and improved to support more formats Webklex#544
1 parent 512f9f5 commit 0a9b263

12 files changed

+302
-18
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) princip
88
### Fixed
99
- Filename sanitization is now optional (enabled via default)
1010
- Address parsing improved and extended to include more cases
11+
- Boundary parsing fixed and improved to support more formats #544
1112

1213
### Added
1314
- Security configuration options added

src/Structure.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,10 @@ private function parsePart(string $context, int $part_number = 0): array {
132132
* @throws InvalidMessageDateException
133133
*/
134134
private function detectParts(string $boundary, string $context, int $part_number = 0): array {
135-
$base_parts = explode( $boundary, $context);
135+
$base_parts = explode( "--".$boundary, $context);
136+
if(count($base_parts) == 0) {
137+
$base_parts = explode($boundary, $context);
138+
}
136139
$final_parts = [];
137140
foreach($base_parts as $ctx) {
138141
$ctx = substr($ctx, 2);

tests/HeaderTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ public function testHeaderParsing(): void {
5151
$header = new Header($raw_header, $this->config);
5252
$subject = $header->get("subject");
5353
$returnPath = $header->get("return_path");
54-
var_dump($returnPath);
5554
/** @var Carbon $date */
5655
$date = $header->get("date")->first();
5756
/** @var Address $from */

tests/fixtures/BooleanDecodedContentTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public function testFixture() : void {
4848
self::assertEquals("application/pdf", $attachment->content_type);
4949
self::assertEquals("1c449aaab4f509012fa5eaa180fd017eb7724ccacabdffc1c6066d3756dcde5c", hash("sha256", $attachment->content));
5050
self::assertEquals(53, $attachment->size);
51-
self::assertEquals(3, $attachment->part_number);
51+
self::assertEquals(2, $attachment->part_number);
5252
self::assertEquals("attachment", $attachment->disposition);
5353
self::assertNotEmpty($attachment->id);
5454
}

tests/fixtures/EmbeddedEmailWithoutContentDispositionEmbeddedTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public function testFixture() : void {
5555
self::assertEquals("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $attachment->content_type);
5656
self::assertEquals("87737d24c106b96e177f9564af6712e2c6d3e932c0632bfbab69c88b0bb934dc", hash("sha256", $attachment->content));
5757
self::assertEquals(40, $attachment->size);
58-
self::assertEquals(3, $attachment->part_number);
58+
self::assertEquals(2, $attachment->part_number);
5959
self::assertEquals("attachment", $attachment->disposition);
6060
self::assertNotEmpty($attachment->id);
6161

@@ -67,7 +67,7 @@ public function testFixture() : void {
6767
self::assertEquals("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $attachment->content_type);
6868
self::assertEquals("87737d24c106b96e177f9564af6712e2c6d3e932c0632bfbab69c88b0bb934dc", hash("sha256", $attachment->content));
6969
self::assertEquals(40, $attachment->size);
70-
self::assertEquals(4, $attachment->part_number);
70+
self::assertEquals(3, $attachment->part_number);
7171
self::assertEquals("attachment", $attachment->disposition);
7272
self::assertNotEmpty($attachment->id);
7373
}

tests/fixtures/EmbeddedEmailWithoutContentDispositionTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public function testFixture() : void {
5454
self::assertEquals("image/jpeg", $attachment->content_type);
5555
self::assertEquals("6b7fa434f92a8b80aab02d9bf1a12e49ffcae424e4013a1c4f68b67e3d2bbcd0", hash("sha256", $attachment->content));
5656
self::assertEquals(96, $attachment->size);
57-
self::assertEquals(3, $attachment->part_number);
57+
self::assertEquals(2, $attachment->part_number);
5858
self::assertEquals("inline", $attachment->disposition);
5959
self::assertNotEmpty($attachment->id);
6060

@@ -66,7 +66,7 @@ public function testFixture() : void {
6666
self::assertEquals("message/rfc822", $attachment->content_type);
6767
self::assertEquals("2476c8b91a93c6b2fe1bfff593cb55956c2fe8e7ca6de9ad2dc9d101efe7a867", hash("sha256", $attachment->content));
6868
self::assertEquals(2073, $attachment->size);
69-
self::assertEquals(5, $attachment->part_number);
69+
self::assertEquals(3, $attachment->part_number);
7070
self::assertNull($attachment->disposition);
7171
self::assertNotEmpty($attachment->id);
7272

@@ -78,7 +78,7 @@ public function testFixture() : void {
7878
self::assertEquals("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $attachment->content_type);
7979
self::assertEquals("87737d24c106b96e177f9564af6712e2c6d3e932c0632bfbab69c88b0bb934dc", hash("sha256", $attachment->content));
8080
self::assertEquals(40, $attachment->size);
81-
self::assertEquals(6, $attachment->part_number);
81+
self::assertEquals(4, $attachment->part_number);
8282
self::assertEquals("attachment", $attachment->disposition);
8383
self::assertNotEmpty($attachment->id);
8484

@@ -90,7 +90,7 @@ public function testFixture() : void {
9090
self::assertEquals("application/x-zip-compressed", $attachment->content_type);
9191
self::assertEquals("87737d24c106b96e177f9564af6712e2c6d3e932c0632bfbab69c88b0bb934dc", hash("sha256", $attachment->content));
9292
self::assertEquals(40, $attachment->size);
93-
self::assertEquals(7, $attachment->part_number);
93+
self::assertEquals(5, $attachment->part_number);
9494
self::assertEquals("attachment", $attachment->disposition);
9595
self::assertNotEmpty($attachment->id);
9696
}

tests/fixtures/MultipleHtmlPartsAndAttachmentsTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public function testFixture() : void {
5757
self::assertEquals("application/pdf", $attachment->content_type);
5858
self::assertEquals("c162adf19e0f67e26ef0b7f791b33a60b2c23b175560a505dc7f9ec490206e49", hash("sha256", $attachment->content));
5959
self::assertEquals(4814, $attachment->size);
60-
self::assertEquals(4, $attachment->part_number);
60+
self::assertEquals(2, $attachment->part_number);
6161
self::assertEquals("inline", $attachment->disposition);
6262
self::assertNotEmpty($attachment->id);
6363

@@ -69,7 +69,7 @@ public function testFixture() : void {
6969
self::assertEquals("application/pdf", $attachment->content_type);
7070
self::assertEquals("a337b37e9d3edb172a249639919f0eee3d344db352046d15f8f9887e55855a25", hash("sha256", $attachment->content));
7171
self::assertEquals(5090, $attachment->size);
72-
self::assertEquals(6, $attachment->part_number);
72+
self::assertEquals(4, $attachment->part_number);
7373
self::assertEquals("inline", $attachment->disposition);
7474
self::assertNotEmpty($attachment->id);
7575
}

tests/fixtures/MultipleNestedAttachmentsTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public function testFixture() : void {
5050
self::assertEquals("image/png", $attachment->content_type);
5151
self::assertEquals("e0e99b0bd6d5ea3ced99add53cc98b6f8eea6eae8ddd773fd06f3489289385fb", hash("sha256", $attachment->content));
5252
self::assertEquals(114, $attachment->size);
53-
self::assertEquals(5, $attachment->part_number);
53+
self::assertEquals(3, $attachment->part_number);
5454
self::assertEquals("inline", $attachment->disposition);
5555
self::assertNotEmpty($attachment->id);
5656

@@ -62,7 +62,7 @@ public function testFixture() : void {
6262
self::assertEquals("image/png", $attachment->content_type);
6363
self::assertEquals("e0e99b0bd6d5ea3ced99add53cc98b6f8eea6eae8ddd773fd06f3489289385fb", hash("sha256", $attachment->content));
6464
self::assertEquals(114, $attachment->size);
65-
self::assertEquals(8, $attachment->part_number);
65+
self::assertEquals(4, $attachment->part_number);
6666
self::assertEquals("attachment", $attachment->disposition);
6767
self::assertNotEmpty($attachment->id);
6868
}

tests/fixtures/NestesEmbeddedWithAttachmentTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public function testFixture() : void {
5050
self::assertEquals("message/rfc822", $attachment->content_type);
5151
self::assertEquals("From: [email protected]\r\nTo: [email protected]\r\nSubject: FIRST\r\nDate: Sat, 28 Apr 2018 14:37:16 -0400\r\nMIME-Version: 1.0\r\nContent-Type: multipart/mixed;\r\n boundary=\"----=_NextPart_000_222_000\"\r\n\r\nThis is a multi-part message in MIME format.\r\n\r\n------=_NextPart_000_222_000\r\nContent-Type: multipart/alternative;\r\n boundary=\"----=_NextPart_000_222_111\"\r\n\r\n\r\n------=_NextPart_000_222_111\r\nContent-Type: text/plain;\r\n charset=\"UTF-8\"\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\nPlease respond directly to this email to update your RMA\r\n\r\n\r\n2018-04-17T11:04:03-04:00\r\n------=_NextPart_000_222_111\r\nContent-Type: text/html;\r\n charset=\"UTF-8\"\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\n<HTML><HEAD></HEAD>\r\n<BODY dir=3Dltr>\r\n<DIV>Please respond directly to this =\r\nemail to=20\r\nupdate your RMA</DIV></BODY></HTML>\r\n\r\n------=_NextPart_000_222_111--\r\n\r\n------=_NextPart_000_222_000\r\nContent-Type: image/png;\r\n name=\"chrome.png\"\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment;\r\n filename=\"chrome.png\"\r\n\r\niVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAB+FBMVEUAAAA/mUPidDHiLi5Cn0Xk\r\nNTPmeUrkdUg/m0Q0pEfcpSbwaVdKskg+lUP4zA/iLi3msSHkOjVAmETdJSjtYFE/lkPnRj3sWUs8\r\nkkLeqCVIq0fxvhXqUkbVmSjwa1n1yBLepyX1xxP0xRXqUkboST9KukpHpUbuvRrzrhF/ljbwalju\r\nZFM4jELaoSdLtElJrUj1xxP6zwzfqSU4i0HYnydMtUlIqUfywxb60AxZqEXaoifgMCXptR9MtklH\r\npEY2iUHWnSjvvRr70QujkC+pUC/90glMuEnlOjVMt0j70QriLS1LtEnnRj3qUUXfIidOjsxAhcZF\r\no0bjNDH0xxNLr0dIrUdmntVTkMoyfL8jcLBRuErhJyrgKyb4zA/5zg3tYFBBmUTmQTnhMinruBzv\r\nvhnxwxZ/st+Ktt5zp9hqota2vtK6y9FemNBblc9HiMiTtMbFtsM6gcPV2r6dwroseLrMrbQrdLGd\r\nyKoobKbo3Zh+ynrgVllZulTsXE3rV0pIqUf42UVUo0JyjEHoS0HmsiHRGR/lmRz/1hjqnxjvpRWf\r\nwtOhusaz0LRGf7FEfbDVmqHXlJeW0pbXq5bec3fX0nTnzmuJuWvhoFFhm0FtrziBsjaAaDCYWC+u\r\nSi6jQS3FsSfLJiTirCOkuCG1KiG+wSC+GBvgyhTszQ64Z77KAAAARXRSTlMAIQRDLyUgCwsE6ebm\r\n5ubg2dLR0byXl4FDQzU1NDEuLSUgC+vr6urq6ubb29vb2tra2tG8vLu7u7uXl5eXgYGBgYGBLiUA\r\nLabIAAABsElEQVQoz12S9VPjQBxHt8VaOA6HE+AOzv1wd7pJk5I2adpCC7RUcHd3d3fXf5PvLkxh\r\neD++z+yb7GSRlwD/+Hj/APQCZWxM5M+goF+RMbHK594v+tPoiN1uHxkt+xzt9+R9wnRTZZQpXQ0T\r\n5uP1IQxToyOAZiQu5HEpjeA4SWIoksRxNiGC1tRZJ4LNxgHgnU5nJZBDvuDdl8lzQRBsQ+s9PZt7\r\ns7Pz8wsL39/DkIfZ4xlB2Gqsq62ta9oxVlVrNZpihFRpGO9fzQw1ms0NDWZz07iGkJmIFH8xxkc3\r\na/WWlubmFkv9AB2SEpDvKxbjidN2faseaNV3zoHXvv7wMODJdkOHAegweAfFPx4G67KluxzottCU\r\n9n8CUqXzcIQdXOytAHqXxomvykhEKN9EFutG22p//0rbNvHVxiJywa8yS2KDfV1dfbu31H8jF1RH\r\niTKtWYeHxUvq3bn0pyjCRaiRU6aDO+gb3aEfEeVNsDgm8zzLy9egPa7Qt8TSJdwhjplk06HH43ZN\r\nJ3s91KKCHQ5x4sw1fRGYDZ0n1L4FKb9/BP5JLYxToheoFCVxz57PPS8UhhEpLBVeAAAAAElFTkSu\r\nQmCC\r\n\r\n------=_NextPart_000_222_000--", $attachment->content);
5252
self::assertEquals(2535, $attachment->size);
53-
self::assertEquals(5, $attachment->part_number);
53+
self::assertEquals(3, $attachment->part_number);
5454
self::assertEquals("attachment", $attachment->disposition);
5555
self::assertNotEmpty($attachment->id);
5656

@@ -62,7 +62,7 @@ public function testFixture() : void {
6262
self::assertEquals("message/rfc822", $attachment->content_type);
6363
self::assertEquals("From: [email protected]\r\nTo: [email protected]\r\nSubject: SECOND\r\nDate: Sat, 28 Apr 2018 13:37:30 -0400\r\nMIME-Version: 1.0\r\nContent-Type: multipart/alternative;\r\n boundary=\"----=_NextPart_000_333_000\"\r\n\r\nThis is a multi-part message in MIME format.\r\n\r\n------=_NextPart_000_333_000\r\nContent-Type: text/plain;\r\n charset=\"UTF-8\"\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\nT whom it may concern:\r\n------=_NextPart_000_333_000\r\nContent-Type: text/html;\r\n charset=\"UTF-8\"\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\n<HTML><HEAD></HEAD>\r\n<BODY dir=3Dltr>\r\n<DIV>T whom it may concern:</DIV>\r\n</BODY></HTML>\r\n\r\n------=_NextPart_000_333_000--", $attachment->content);
6464
self::assertEquals(631, $attachment->size);
65-
self::assertEquals(6, $attachment->part_number);
65+
self::assertEquals(4, $attachment->part_number);
6666
self::assertEquals("attachment", $attachment->disposition);
6767
self::assertNotEmpty($attachment->id);
6868
}

tests/fixtures/PecTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public function testFixture() : void {
5151
self::assertEquals("application/xml", $attachment->content_type);
5252
self::assertEquals("<xml/>", $attachment->content);
5353
self::assertEquals(8, $attachment->size);
54-
self::assertEquals(4, $attachment->part_number);
54+
self::assertEquals(3, $attachment->part_number);
5555
self::assertEquals("inline", $attachment->disposition);
5656
self::assertNotEmpty($attachment->id);
5757

@@ -63,7 +63,7 @@ public function testFixture() : void {
6363
self::assertEquals("message/rfc822", $attachment->content_type);
6464
self::assertEquals("To: [email protected]\r\nFrom: [email protected]\r\nSubject: test-subject\r\nDate: Mon, 2 Oct 2017 12:13:50 +0200\r\nContent-Type: text/plain; charset=iso-8859-15; format=flowed\r\nContent-Transfer-Encoding: 7bit\r\n\r\ntest-content", $attachment->content);
6565
self::assertEquals(216, $attachment->size);
66-
self::assertEquals(5, $attachment->part_number);
66+
self::assertEquals(4, $attachment->part_number);
6767
self::assertEquals("inline", $attachment->disposition);
6868
self::assertNotEmpty($attachment->id);
6969

@@ -75,7 +75,7 @@ public function testFixture() : void {
7575
self::assertEquals("application/x-pkcs7-signature", $attachment->content_type);
7676
self::assertEquals("1", $attachment->content);
7777
self::assertEquals(4, $attachment->size);
78-
self::assertEquals(7, $attachment->part_number);
78+
self::assertEquals(5, $attachment->part_number);
7979
self::assertEquals("attachment", $attachment->disposition);
8080
self::assertNotEmpty($attachment->id);
8181
}

tests/issues/Issue544Test.php

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
/*
3+
* File: Issue410Test.php
4+
* Category: -
5+
* Author: M.Goldenbaum
6+
* Created: 23.06.23 20:41
7+
* Updated: -
8+
*
9+
* Description:
10+
* -
11+
*/
12+
13+
namespace Tests\issues;
14+
15+
use PHPUnit\Framework\TestCase;
16+
use Tests\fixtures\FixtureTestCase;
17+
use Webklex\PHPIMAP\Attachment;
18+
use Webklex\PHPIMAP\ClientManager;
19+
use Webklex\PHPIMAP\Exceptions\AuthFailedException;
20+
use Webklex\PHPIMAP\Exceptions\ConnectionFailedException;
21+
use Webklex\PHPIMAP\Exceptions\ImapBadRequestException;
22+
use Webklex\PHPIMAP\Exceptions\ImapServerErrorException;
23+
use Webklex\PHPIMAP\Exceptions\InvalidMessageDateException;
24+
use Webklex\PHPIMAP\Exceptions\MaskNotFoundException;
25+
use Webklex\PHPIMAP\Exceptions\MessageContentFetchingException;
26+
use Webklex\PHPIMAP\Exceptions\ResponseException;
27+
use Webklex\PHPIMAP\Exceptions\RuntimeException;
28+
use Webklex\PHPIMAP\Message;
29+
30+
class Issue544Test extends FixtureTestCase {
31+
32+
/**
33+
* @throws RuntimeException
34+
* @throws MessageContentFetchingException
35+
* @throws ResponseException
36+
* @throws ImapBadRequestException
37+
* @throws InvalidMessageDateException
38+
* @throws ConnectionFailedException
39+
* @throws \ReflectionException
40+
* @throws ImapServerErrorException
41+
* @throws AuthFailedException
42+
* @throws MaskNotFoundException
43+
*/
44+
public function testIssueEmail() {
45+
$message = $this->getFixture("issue-544.eml");
46+
47+
self::assertSame("Test bad boundary", (string)$message->subject);
48+
49+
$attachments = $message->getAttachments();
50+
51+
self::assertSame(1, $attachments->count());
52+
53+
/** @var Attachment $attachment */
54+
$attachment = $attachments->first();
55+
self::assertSame("file.pdf", $attachment->name);
56+
self::assertSame("file.pdf", $attachment->filename);
57+
self::assertStringStartsWith("%PDF-1.4", $attachment->content);
58+
self::assertStringEndsWith("%%EOF\n", $attachment->content);
59+
self::assertSame(14938, $attachment->size);
60+
}
61+
}

0 commit comments

Comments
 (0)