Skip to content

Commit e527bf3

Browse files
committed
Decode partially encoded address names Webklex#511
1 parent 4289d41 commit e527bf3

File tree

5 files changed

+73
-10
lines changed

5 files changed

+73
-10
lines changed

CHANGELOG.md

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

1314
### Added
1415
- Security configuration options added

src/Decoder/HeaderDecoder.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,11 @@ public function getEncoding(object|string $structure): string {
6868
if (property_exists($structure, 'parameters')) {
6969
foreach ($structure->parameters as $parameter) {
7070
if (strtolower($parameter->attribute) == "charset") {
71-
return EncodingAliases::get($parameter->value, $this->fallback_encoding);
71+
return EncodingAliases::get($parameter->value == "default" ? EncodingAliases::detectEncoding($parameter->value) : $parameter->value, $this->fallback_encoding);
7272
}
7373
}
7474
} elseif (property_exists($structure, 'charset')) {
75-
return EncodingAliases::get($structure->charset, $this->fallback_encoding);
75+
return EncodingAliases::get($structure->charset == "default" ? EncodingAliases::detectEncoding($structure->charset) : $structure->charset, $this->fallback_encoding);
7676
} elseif (is_string($structure) === true) {
7777
$result = mb_detect_encoding($structure);
7878
return $result === false ? $this->fallback_encoding : $result;

src/Header.php

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -480,16 +480,23 @@ private function parseAddresses($list): array {
480480
if (!property_exists($address, 'personal')) {
481481
$address->personal = false;
482482
} else {
483-
$personalParts = $this->decoder->mimeHeaderDecode($address->personal);
484-
485-
$address->personal = '';
486-
foreach ($personalParts as $p) {
487-
$address->personal .= $this->decoder->convertEncoding($p->text, $this->decoder->getEncoding($p));
488-
}
483+
$personal_slices = explode(" ", $address->personal);
484+
$address->personal = "";
485+
foreach ($personal_slices as $slice) {
486+
$personalParts = $this->decoder->mimeHeaderDecode($slice);
487+
488+
$personal = '';
489+
foreach ($personalParts as $p) {
490+
$personal .= $this->decoder->convertEncoding($p->text, $this->decoder->getEncoding($p));
491+
}
489492

490-
if (str_starts_with($address->personal, "'")) {
491-
$address->personal = str_replace("'", "", $address->personal);
493+
if (str_starts_with($personal, "'")) {
494+
$personal = str_replace("'", "", $personal);
495+
}
496+
$personal = $this->decoder->decode($personal);
497+
$address->personal .= $personal . " ";
492498
}
499+
$address->personal = trim(rtrim($address->personal));
493500
}
494501

495502
if ($address->host == ".SYNTAX-ERROR.") {

tests/issues/Issue511Test.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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\EncodingAliases;
20+
use Webklex\PHPIMAP\Exceptions\AuthFailedException;
21+
use Webklex\PHPIMAP\Exceptions\ConnectionFailedException;
22+
use Webklex\PHPIMAP\Exceptions\ImapBadRequestException;
23+
use Webklex\PHPIMAP\Exceptions\ImapServerErrorException;
24+
use Webklex\PHPIMAP\Exceptions\InvalidMessageDateException;
25+
use Webklex\PHPIMAP\Exceptions\MaskNotFoundException;
26+
use Webklex\PHPIMAP\Exceptions\MessageContentFetchingException;
27+
use Webklex\PHPIMAP\Exceptions\ResponseException;
28+
use Webklex\PHPIMAP\Exceptions\RuntimeException;
29+
use Webklex\PHPIMAP\Message;
30+
31+
class Issue511Test extends FixtureTestCase {
32+
33+
/**
34+
* @throws RuntimeException
35+
* @throws MessageContentFetchingException
36+
* @throws ResponseException
37+
* @throws ImapBadRequestException
38+
* @throws InvalidMessageDateException
39+
* @throws ConnectionFailedException
40+
* @throws \ReflectionException
41+
* @throws ImapServerErrorException
42+
* @throws AuthFailedException
43+
* @throws MaskNotFoundException
44+
*/
45+
public function testIssueEmail() {
46+
$message = $this->getFixture("issue-511.eml");
47+
self::assertSame("RE: [EXTERNAL] Re: Lorem Ipsum /40 one", (string)$message->subject);
48+
self::assertSame("COMPANYNAME | usługi <sender@sender_domain.tld>", (string)$message->from->first());
49+
}
50+
}

tests/messages/issue-511.eml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
From: COMPANYNAME | =?iso-8859-2?q?us=B3ugi?= <sender@sender_domain.tld>
2+
To: receipent@receipent_domain.tld
3+
Subject: =?utf-8?B?UkU6IFtFWFRFUk5BTF0gUmU6IExvcmVtIElwc3VtIC8=?= =?utf-8?Q?40_one?=
4+
5+
Test message

0 commit comments

Comments
 (0)