Menu

#10 function MbEncode() returns UTF-8 strings unencoded

1.0
closed
None
2026-08-11
2026-08-10
No

This issue returns UTF-8 strings containing non-ASCII characters unchanged, producing invalid mail headers on some mail clients (e.g. Apple Mail on iPhone displays "ü" instead of "ü").
ASCII strings should be returned unchanged; UTF-8 strings containing non-ASCII characters should be MIME encoded.
The original MbEncode() condition returned strings containing multibyte UTF-8 characters unchanged. This caused raw UTF-8 bytes in the Subject header and incorrect display in some clients, notably Apple Mail on iPhone.

After reversing the ASCII/multibyte test and encoding only non-ASCII subjects, the generated Subject header is correctly emitted using RFC 2047 encoded words.

Current code starting line 1466

    function MbEncode($str, $len = 70)
    {
        $str = self::SafeStr($str);
        if (mb_strlen($str) != strlen($str)) {
            return $str;
        }
        if (function_exists("mb_internal_encoding") && function_exists("mb_encode_mimeheader")) {
            mb_internal_encoding("UTF-8");
            return mb_encode_mimeheader($str, "UTF-8");
        } else {
            $prefs = ["scheme" => "Q", "input-charset" => "utf-8", "output-charset" => "utf-8", "line-length" => $len];
            return iconv_mime_encode("string", $str, $prefs);
        }
    }

Fix

    function MbEncode($str, $len = 70)
    {
        $str = self::SafeStr($str);

        // pure ASCII needs no MIME-Coding
        if (mb_strlen($str, 'UTF-8') === strlen($str)) {
            return $str;
        }

        if (
            function_exists('mb_internal_encoding')
            && function_exists('mb_encode_mimeheader')
        ) {
            mb_internal_encoding('UTF-8');

            return mb_encode_mimeheader(
                $str,
                'UTF-8',
                'B',
                self::CRLF,
                9 // Length of "Subject: "
            );
        }

        $prefs = [
            'scheme'         => 'B',
            'input-charset'  => 'UTF-8',
            'output-charset' => 'UTF-8',
            'line-length'    => $len,
            'line-break-chars' => self::CRLF,
        ];

        return iconv_mime_encode('Subject', $str, $prefs);
    }

Discussion

  • Andy Prevost (CodeworxTech)

    Confirmed bug, but fix is at the correct architectural point rather than applying the supplied patch verbatim.
    The intended behavior should be:
    Plain ASCII subject → returned unchanged.
    UTF-8/non-ASCII subject → RFC 2047 encoded.
    MbEncode() returns only the encoded subject value, not Subject: ....
    Avoid encoding the same subject twice.
    Preserve proper CRLF folding.
    The existing call sites show that MbEncode() is used for both custom-header values and the Subject, so we should keep its contract as "encode this header value", not "construct a complete header."

    • note: fixing a double-encoding issue first, then fix applied.
      (contained in Aug 10 2026 release)
     
  • Andy Prevost (CodeworxTech)

    • status: open --> closed
     

Log in to post a comment.