ISO-2022-JP emails are garbled in Mail 5.10.12 [Minimal fix available]
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 1k
- Forks
- 348
- Avg merge
- 12h 28m
- Merged PRs (30d)
- 91
Description
Steps to reproduce
-
Set up Nextcloud Server 34.0.0 with Nextcloud Mail 5.10.12.
-
Use a PHP environment with
mbstringandiconvenabled. -
Receive an email encoded as ISO-2022-JP, for example:
Content-Type: text/plain; charset=ISO-2022-JP Content-Transfer-Encoding: 7bit -
Open the email using Nextcloud Mail.
-
Observe that the Japanese text is garbled or replaced with
?.
The issue can be reproduced with emails sent by Cybozu MailWise 5.4.7.
Expected behavior
The ISO-2022-JP encoded email should be correctly decoded and displayed as UTF-8 Japanese text.
Actual behavior
Japanese text in ISO-2022-JP emails is displayed incorrectly, with characters being garbled or replaced with ?.
The issue does not occur when the same message body is manually converted using PHP's mb_convert_encoding().
Mail app version
5.10.12
Nextcloud version
docker nextcloud:34.0.0-fpm-alpine
Mailserver or service
Cybozu MailWise 5.4.7
Operating system
uname -a Linux iris 7.0.0-28-generic #28~24.04.1-Ubuntu SMP PREEMPT_DYNAMIC Wed Jul 1 15:50:57 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
PHP engine version
PHP 8.3
Nextcloud memory caching
No response
Web server
Nginx
Database
MariaDB
Additional info
Environment
- Nextcloud Server: 34.0.0
- Nextcloud Mail: 5.10.12
- PHP: Docker image based on Alpine Linux
- PHP
mbstring: enabled - PHP
iconv: enabled - iconv implementation:
libiconv - libiconv version: 1.18
Investigation
The issue was traced to:
lib/IMAP/Charset/Converter.php
The relevant code is:
if (in_array($charset, mb_list_encodings(), true)) {
$converted = mb_convert_encoding($data, 'UTF-8', $charset);
} else {
$converted = iconv($charset, 'UTF-8', $data);
}
For the affected messages, Horde provides the charset as:
iso-2022-jp
However, in this PHP environment:
in_array("iso-2022-jp", mb_list_encodings(), true)
→ false
in_array("ISO-2022-JP", mb_list_encodings(), true)
→ true
Because the comparison is case-sensitive, iso-2022-jp is not recognized as an encoding supported by mbstring, and the code falls back to iconv().
Conversion results
The original ISO-2022-JP message body was tested directly.
Using mb_convert_encoding():
$r = mb_convert_encoding($s, "UTF-8", "ISO-2022-JP");
produces the correct Japanese text.
Using iconv():
$r = iconv("ISO-2022-JP", "UTF-8", $s);
produces:
Notice: iconv(): Detected an illegal character in input string
and returns false.
The data passed to Converter::convert() was also inspected. The affected plain-text part contained the expected ISO-2022-JP escape sequence:
1b 24 42
(ESC $ B), confirming that the message body itself is valid ISO-2022-JP data at that point.
Root cause
The issue appears to be caused by the case-sensitive comparison of the MIME charset name with the encoding names returned by mb_list_encodings().
The processing path is:
MIME charset: iso-2022-jp
↓
mb_list_encodings() comparison
↓
case-sensitive mismatch
↓
fallback to iconv()
↓
libiconv: "Detected an illegal character in input string"
↓
conversion failure / garbled text
Workaround / minimal patch
The following minimal change fixes the issue in the affected environment:
if (in_array(strtoupper($charset), array_map('strtoupper', mb_list_encodings()), true)) {
$converted = mb_convert_encoding($data, 'UTF-8', $charset);
} else {
$converted = iconv($charset, 'UTF-8', $data);
}
After applying this change, the affected ISO-2022-JP emails are displayed correctly.
This also confirms that the problem is not caused by corrupted email data or an inability of PHP's mbstring extension to decode ISO-2022-JP.
Request
Please consider making charset matching case-insensitive so that MIME charset names such as iso-2022-jp are correctly recognized as encodings supported by mbstring.
If appropriate, please also consider backporting the fix to supported maintenance versions.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with lib/IMAP/Charset/Converter.php and trace Converter::convert() for the lowercase iso-2022-jp charset. Reproduce the mb_list_encodings() comparison and verify the conversion path with the provided ISO-2022-JP message data. Done means the affected Japanese email displays correctly without the iconv conversion failure.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 82/100