Skip to content

Commit 301186b

Browse files
author
Sebastian Krätzig
committed
543: Fix incorrect MIME decoding
1 parent 8e2f620 commit 301186b

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
@@ -1329,6 +1329,49 @@ public function downloadAttachment(DataPartInfo $dataInfo, array $params, object
13291329
return $attachment;
13301330
}
13311331

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

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

13841400
return $newString;

0 commit comments

Comments
 (0)