Skip to content

Commit

Permalink
parse broken boundaries
Browse files Browse the repository at this point in the history
  • Loading branch information
arukompas committed Aug 25, 2023
1 parent 94d5da9 commit 7668596
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/Message.php
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ protected function parse()
}

if (preg_match('/^(?<key>[A-Za-z\-0-9]+): (?<value>.*)$/', $line, $matches)) {
if (strtolower($matches['key']) === 'content-type' && !isset($this->boundary)) {
if (strtolower($matches['key']) === 'content-type' && !isset($this->boundary) && !str_contains($matches['value'], 'multipart/mixed')) {
// this might be a single-part message. Let's start collecting the body.
$collectingBody = true;
$currentBody = '';
Expand All @@ -249,6 +249,14 @@ protected function parse()
continue;
}

if (preg_match("~^--(?<boundary>[0-9A-Za-z'()+_,-./:=?]{0,68}[0-9A-Za-z'()+_,-./=?])~", $line, $matches)) {
$this->boundary = trim($matches['boundary']);
$collectingBody = true;
$currentBody = '';
$currentBodyHeaders = [];
continue;
}

// The line is not part of the email message. Let's remove it altogether.
$this->message = ltrim(substr($this->message, strlen($line)));
}
Expand Down
37 changes: 37 additions & 0 deletions tests/Unit/MessageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -296,3 +296,40 @@
EOF)
->and($message->getPArts()[1]->getContent())->toBe('This is a test string');
});

it('still parses with a broken boundary', function () {
$messageString = <<<EOF
From: [email protected]
To: [email protected]
Subject: This is an email with common headers
Date: Thu, 24 Aug 2023 21:15:01 PST
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary¨cQXEYh
--a8cQXEYh
Content-Type: text/html; charset="utf-8"
<html>
<head>
<title>This is an HTML email</title>
</head>
<body>
<h1>This is the HTML version of the email</h1>
</body>
</html>--a8cQXEYh
Content-Type: text/plain; name=test.txt
Content-Transfer-Encoding: base64
Content-Disposition: attachment; name=test.txt;
filename="test.txt"; name="test.txt"
--a8cQXEYh--
EOF;
$messageString = str_replace("\n", "\r\n", $messageString);

$message = Message::fromString($messageString);

expect($message->getParts())->toHaveCount(2)
->and($message->getParts()[1]->isAttachment())->toBe(true)
->and($message->getParts()[1]->getContent())->toBeEmpty();
});

0 comments on commit 7668596

Please sign in to comment.