Skip to content

Commit 48cf726

Browse files
committed
Ignore ws between rfc2047 parts in q-part #240
If two mime-encoded parts are found in a single quoted-part, ignore any whitespace between them.
1 parent 3a813b3 commit 48cf726

File tree

3 files changed

+54
-2
lines changed

3 files changed

+54
-2
lines changed

src/Header/Part/QuotedLiteralPart.php

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,38 @@
99

1010
/**
1111
* A quoted literal header string part. The value of the part is stripped of CR
12-
* and LF characters, but otherwise not transformed or changed in any way.
12+
* and LF characters, and whitespace between two adjacent MimeTokens is removed.
1313
*
1414
* @author Zaahid Bateson
1515
*/
1616
class QuotedLiteralPart extends ContainerPart
1717
{
18+
/**
19+
* Strips spaces found between two adjacent MimeToken parts.
20+
* Other whitespace is returned as-is.
21+
*
22+
* @param HeaderPart[] $parts
23+
* @return HeaderPart[]
24+
*/
1825
protected function filterIgnoredSpaces(array $parts) : array
1926
{
20-
return $parts;
27+
$filtered = \array_reduce(
28+
\array_keys($parts),
29+
function($carry, $key) use ($parts) {
30+
$cur = $parts[$key];
31+
$last = ($carry !== null) ? \end($carry) : null;
32+
$next = (count($parts) > $key + 1) ? $parts[$key + 1] : null;
33+
if ($last !== null && $next !== null && $cur->isSpace && (
34+
$last->canIgnoreSpacesAfter
35+
&& $next->canIgnoreSpacesBefore
36+
&& $last instanceof MimeToken
37+
&& $next instanceof MimeToken
38+
)) {
39+
return $carry;
40+
}
41+
return \array_merge($carry ?? [], [$cur]);
42+
}
43+
);
44+
return $filtered;
2145
}
2246
}

tests/MailMimeParser/Header/Consumer/ParameterValueConsumerServiceTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,16 @@ public function testWithQuotedHeaderEncodedValue() : void
9898
$ret = $this->consumer->__invoke('"=?US-ASCII?Q?value?="');
9999
$this->assertEquals('value', $ret[0]->getValue());
100100
}
101+
102+
public function testWithQuotedHeaderMultipleEncodedValues() : void
103+
{
104+
$ret = $this->consumer->__invoke('"=?US-ASCII?Q?Kilgore?= =?US-ASCII?Q?Trout?="');
105+
$this->assertEquals('KilgoreTrout', $ret[0]->getValue());
106+
}
107+
108+
public function testWithQuotedHeaderMultipleEncodedValuesAndLinesBetween() : void
109+
{
110+
$ret = $this->consumer->__invoke("\"=?US-ASCII?Q?Kilg?= \r\n =?US-ASCII?Q?or?= =?US-ASCII?Q?e_Trout?=\"");
111+
$this->assertEquals('Kilgore Trout', $ret[0]->getValue());
112+
}
101113
}

tests/MailMimeParser/Header/Consumer/QuotedStringMimeLiteralPartConsumerServiceTest.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,20 @@ public function testConsumeMimeEncodedValue() : void
6363
$this->assertInstanceOf(QuotedLiteralPart::class, $ret[0]);
6464
$this->assertEquals('Kilgore Trout', $ret[0]->getValue());
6565
}
66+
67+
public function testWithQuotedHeaderMultipleEncodedValues() : void
68+
{
69+
$ret = $this->consumer->__invoke('=?US-ASCII?Q?Kilgore?= =?US-ASCII?Q?Trout?=');
70+
$this->assertNotEmpty($ret);
71+
$this->assertCount(1, $ret);
72+
$this->assertEquals('KilgoreTrout', $ret[0]->getValue());
73+
}
74+
75+
public function testWithQuotedHeaderMultipleEncodedValuesAndLinesBetween() : void
76+
{
77+
$ret = $this->consumer->__invoke("=?US-ASCII?Q?Kilg?= \r\n =?US-ASCII?Q?or?= =?US-ASCII?Q?e_Trout?=");
78+
$this->assertNotEmpty($ret);
79+
$this->assertCount(1, $ret);
80+
$this->assertEquals('Kilgore Trout', $ret[0]->getValue());
81+
}
6682
}

0 commit comments

Comments
 (0)