Skip to content

ISO-2022-JP emails are garbled in Mail 5.10.12 [Minimal fix available] #13472

Description

@neconohitomi

Steps to reproduce

  1. Set up Nextcloud Server 34.0.0 with Nextcloud Mail 5.10.12.

  2. Use a PHP environment with mbstring and iconv enabled.

  3. Receive an email encoded as ISO-2022-JP, for example:

    Content-Type: text/plain; charset=ISO-2022-JP
    Content-Transfer-Encoding: 7bit
    
  4. Open the email using Nextcloud Mail.

  5. 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.

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions