Skip to content

Commit b5dfb69

Browse files
committed
fixed: message id, small refactoring the boundary
1 parent f05c8e4 commit b5dfb69

File tree

8 files changed

+69
-23
lines changed

8 files changed

+69
-23
lines changed

src/HeadersTrait.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public function findInHeader($header, $type, $default = null)
9393
$len = strlen($type);
9494
foreach ($this->getHeader($header) as $head) {
9595
if (strncasecmp($head, $type, $len) === 0) {
96-
return trim(substr($head, $len), "= \t\"'");
96+
return trim(ltrim(substr($head, $len), " \t="), " \t\"'");
9797
}
9898
}
9999
return $default;

src/Message.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -192,15 +192,16 @@ protected function findTextParts($mime = 'text/html')
192192
) {
193193
$parts[] = $this;
194194
}
195-
if ($this->boundary === null) {
195+
if (($boundary = $this->getBoundary()) === null) {
196196
return $parts;
197197
}
198-
$ids = [$this->boundary];
199-
198+
$boundaries = [$boundary];
200199
foreach ($this->parts as $part) {
201-
if (in_array($part->getId(), $ids) && ($type = $part->getMimeType()) !== null) {
200+
if (in_array($part->getParentBoundary(), $boundaries) && ($type = $part->getMimeType()) !== null) {
202201
if ($type === 'multipart/alternative' || $type === 'multipart/related') {
203-
$ids[] = $part->boundary;
202+
if (($boundary = $part->getBoundary()) !== null) {
203+
$boundaries[] = $boundary;
204+
}
204205
continue;
205206
}
206207
if (
@@ -225,7 +226,7 @@ protected function replaceCid($html)
225226
* @var Part $attachment
226227
*/
227228
if (
228-
($id = $attachment->getContentID()) !== null
229+
($id = $attachment->getID()) !== null
229230
&& ($mime = $attachment->getMimeType()) !== null
230231
&& strncasecmp($mime, 'image/', 6) === 0
231232
&& strpos($html, "cid:{$id}") !== false

src/Mime.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,6 @@ class Mime
1818
{
1919
use HeadersTrait;
2020

21-
/**
22-
* @var string
23-
*/
24-
public $boundary;
2521
/**
2622
* @var Stream
2723
*/
@@ -101,14 +97,22 @@ public function getAccessType()
10197
/**
10298
* @return null|string
10399
*/
104-
public function getContentID()
100+
public function getID()
105101
{
106102
if ($this->hasHeader('content-id')) {
107-
return trim(str_replace(['<', '>'], '', $this->getHeader('content-id')[0]));
103+
return trim($this->getHeader('content-id')[0], " <>\t\n\r\0\x0B");
108104
}
109105
return null;
110106
}
111107

108+
/**
109+
* @return null|string
110+
*/
111+
public function getBoundary()
112+
{
113+
return $this->findInHeader('content-type', 'boundary');
114+
}
115+
112116
/**
113117
* @return null|string
114118
*/

src/Part.php

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,26 @@
1212
*/
1313
class Part extends Mime
1414
{
15-
protected $id;
15+
/**
16+
* @var string
17+
*/
18+
private $_parentBoundary;
1619

17-
public function __construct($id)
20+
/**
21+
* Part constructor.
22+
* @param string $parentBoundary
23+
*/
24+
public function __construct($parentBoundary)
1825
{
19-
$this->id = $id;
26+
$this->_parentBoundary = $parentBoundary;
2027
}
2128

22-
public function getId()
29+
/**
30+
* @return null|string
31+
*/
32+
public function getParentBoundary()
2333
{
24-
return $this->id;
34+
return $this->_parentBoundary;
2535
}
2636

2737
}

src/parser/Email.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,11 @@ protected function bindBoundary($type, $value)
146146
&& strcasecmp($value[0], 'Content-Type') === 0
147147
&& preg_match('/boundary(?:=|\s=)([^;]+)/i', $value[1], $out)
148148
) {
149-
$id = trim(str_replace(['"', "'"], '', $out[1]));
149+
$id = trim($out[1], " \t\"'");
150150
$this->boundary['--' . $id] = [self::T_START_BOUNDARY, $id];
151151
$this->boundary['--' . $id . '--'] = [self::T_END_BOUNDARY, $id];
152152
} else if ($type === self::T_START_BOUNDARY) {
153153
$this->allowedHeader = true;
154-
$this->context()->boundary = $value;
155154
$this->insertPart();
156155
$this->part = new Part($value);
157156
}

tests/BoundaryTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,21 @@ public function testParse()
3131
["Content-type: multipart/mixed; boundary=\"te\n st\"", 'new line'],
3232
['Content-Type: "multipart/mixed"; boundary="te st"', '>"<'],
3333
["Content-Type: 'multipart/mixed'; boundary='te st'", ">'<"],
34+
['Content-Type: "multipart/mixed"; boundary = "te st"', "with spaces"],
35+
["Content-Type: \"multipart/mixed\"; boundary\t=\t\"te st\"", "with tab"],
3436
] as $eml) {
3537
$parser = new Email();
3638
$parser->parse($eml[0]);
3739
$this->assertEquals($expected, $this->getProperty('bashkarev\email\parser\Email', 'boundary')->getValue($parser), $eml[1]);
3840
}
41+
42+
$parser = new Email();
43+
$parser->parse('Content-Type: multipart/alternative; boundary="=felis-alternative=20170125210403=141032"');
44+
$this->assertEquals([
45+
'--=felis-alternative=20170125210403=141032' => [Email::T_START_BOUNDARY, '=felis-alternative=20170125210403=141032'],
46+
'--=felis-alternative=20170125210403=141032--' => [Email::T_END_BOUNDARY, '=felis-alternative=20170125210403=141032'],
47+
], $this->getProperty('bashkarev\email\parser\Email', 'boundary')->getValue($parser));
48+
3949
}
4050

4151
public function testMultipartAlternative()

tests/HeaderTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ public function testFindInHeader()
5353
['CONTENT-TYPE', 'TEXT/PLAIN;CHARSET="UTF-8"', 'UTF-8', 'uppercase'],
5454
['Content-Type', 'text/plain;charset=utf-8', 'utf-8', 'without quotes'],
5555
['Content-Type', "text/plain;charset='utf-8'", 'utf-8', 'quotes'],
56-
['Content-Type', 'text/plain;charset= utf-8 ', 'utf-8', 'with spaces'],
57-
['Content-Type', 'text/plain;charset= utf-8 ', 'utf-8', 'with spaces 2'],
58-
['Content-Type', "text/plain;charset=\tutf-8\t", 'utf-8', 'with tab'],
56+
['Content-Type', 'text/plain;charset = utf-8 ', 'utf-8', 'with spaces'],
57+
['Content-Type', 'text/plain;charset = utf-8 ', 'utf-8', 'with spaces 2'],
58+
['Content-Type', "text/plain;charset\t=\tutf-8\t", 'utf-8', 'with tab'],
5959
] as $item) {
6060
list($header, $value, $expected, $message) = $item;
6161
$mime = new Mime();

tests/MimeTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,26 @@ public function testMessageRFC822()
108108
});
109109
}
110110

111+
public function testBoundary()
112+
{
113+
$mime = new Mime();
114+
$mime->setHeader('Content-Type', 'multipart/alternative; boundary="=felis-alternative=20170125210403=141032"');
115+
$this->assertEquals('=felis-alternative=20170125210403=141032', $mime->getBoundary(), '');
116+
}
117+
118+
public function testId()
119+
{
120+
foreach ([
121+
['<id>', 'id', 'simple'],
122+
['< id >', 'id', 'space'],
123+
[' < id > ', 'id', 'space'],
124+
["\t<id>\t", 'id', 'tab'],
125+
] as $data) {
126+
list($value, $expected, $message) = $data;
127+
$mime = new Mime();
128+
$mime->setHeader('Content-Id', $value);
129+
$this->assertEquals($expected, $mime->getID(), $message);
130+
}
131+
}
132+
111133
}

0 commit comments

Comments
 (0)