Skip to content

Commit e229515

Browse files
authored
Merge pull request #579 from barbushin/543/Fix-encoding-issues
543: Fix incorrect MIME decoding
2 parents 36aa169 + 301186b commit e229515

File tree

2 files changed

+47
-30
lines changed

2 files changed

+47
-30
lines changed

src/PhpImap/DataPartInfo.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,9 @@ protected function decodeAfterFetch(): string
108108
protected function convertEncodingAfterFetch(): string
109109
{
110110
if (isset($this->charset) and !empty(\trim($this->charset))) {
111-
$this->data = $this->mail->decodeMimeStr(
112-
(string) $this->data // Data to convert
111+
$this->data = $this->mail->convertToUtf8(
112+
(string) $this->data, // Data to convert
113+
$this->charset
113114
);
114115
}
115116

src/PhpImap/Mailbox.php

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,6 +1328,49 @@ public function downloadAttachment(DataPartInfo $dataInfo, array $params, object
13281328
return $attachment;
13291329
}
13301330

1331+
/**
1332+
* Converts a string to UTF-8
1333+
*
1334+
* @param string $string MIME string to decode
1335+
* @param string $fromCharset Charset to convert from
1336+
*
1337+
* @return string Converted string if conversion was successful, or the original string if not
1338+
*/
1339+
public function convertToUtf8(string $string, string $fromCharset): string
1340+
{
1341+
$fromCharset = mb_strtolower($fromCharset);
1342+
$newString = '';
1343+
1344+
if ('default' === $fromCharset) {
1345+
$fromCharset = $this->decodeMimeStrDefaultCharset;
1346+
}
1347+
1348+
switch ($fromCharset) {
1349+
case 'default': // Charset default is already ASCII (not encoded)
1350+
case 'utf-8': // Charset UTF-8 is OK
1351+
$newString .= $string;
1352+
break;
1353+
default:
1354+
// If charset exists in mb_list_encodings(), convert using mb_convert function
1355+
if (\in_array($fromCharset, $this->lowercase_mb_list_encodings(), true)) {
1356+
$newString .= \mb_convert_encoding($string, 'UTF-8', $fromCharset);
1357+
} else {
1358+
// Fallback: Try to convert with iconv()
1359+
$iconv_converted_string = @\iconv($fromCharset, 'UTF-8', $string);
1360+
if (!$iconv_converted_string) {
1361+
// If iconv() could also not convert, return string as it is
1362+
// (unknown charset)
1363+
$newString .= $string;
1364+
} else {
1365+
$newString .= $iconv_converted_string;
1366+
}
1367+
}
1368+
break;
1369+
}
1370+
1371+
return $newString;
1372+
}
1373+
13311374
/**
13321375
* Decodes a mime string.
13331376
*
@@ -1350,34 +1393,7 @@ public function decodeMimeStr(string $string): string
13501393
}
13511394

13521395
foreach ($elements as $element) {
1353-
$charset = \strtolower($element->charset);
1354-
1355-
if ('default' === $charset) {
1356-
$charset = $this->decodeMimeStrDefaultCharset;
1357-
}
1358-
1359-
switch ($charset) {
1360-
case 'default': // Charset default is already ASCII (not encoded)
1361-
case 'utf-8': // Charset UTF-8 is OK
1362-
$newString .= $element->text;
1363-
break;
1364-
default:
1365-
// If charset exists in mb_list_encodings(), convert using mb_convert function
1366-
if (\in_array($charset, $this->lowercase_mb_list_encodings())) {
1367-
$newString .= \mb_convert_encoding($element->text, 'UTF-8', $charset);
1368-
} else {
1369-
// Fallback: Try to convert with iconv()
1370-
$iconv_converted_string = @\iconv($charset, 'UTF-8', $element->text);
1371-
if (!$iconv_converted_string) {
1372-
// If iconv() could also not convert, return string as it is
1373-
// (unknown charset)
1374-
$newString .= $element->text;
1375-
} else {
1376-
$newString .= $iconv_converted_string;
1377-
}
1378-
}
1379-
break;
1380-
}
1396+
$newString .= $this->convertToUtf8($element->text, $element->charset);
13811397
}
13821398

13831399
return $newString;

0 commit comments

Comments
 (0)