#1148757 sympa: WWSympa dates shown as mojibake in UTF-8 locales on Perl 5.40 (gettext_strftime double-encoding)

Package:
sympa
Source:
sympa
Description:
Modern mailing list manager
Submitter:
TANAKA Toshihisa
Date:
2026-09-23 08:35:02 UTC
Severity:
normal
#1148757#5
Date:
2026-09-23 08:24:35 UTC
From:
To:
Dear Maintainer,

On Debian 13 (trixie) with Perl 5.40.1, the WWSympa web interface
displays localized (non-English) dates as mojibake. All date/time
values rendered through Sympa::Language::gettext_strftime() are
double-encoded; e.g. a Japanese date shows as
"2026å¹´08æ15æ¥..." instead of "2026年08月15日...".
Only locale-formatted date strings are affected; other localized
text (from the translation catalog) renders correctly.

Root cause
----------
Since Perl 5.39.8, POSIX::strftime() under a UTF-8 locale returns a
string that has the utf8 flag SET, but whose internal content is
already a UTF-8 byte sequence (not decoded characters). This is a
contradictory state (flag set, but bytes not characters).

gettext_strftime() in lib/Sympa/Language.pm ends with:

     my $ret = POSIX::strftime($format, @args);
     Encode::_utf8_off($ret);

On Perl 5.40.1, Encode::_utf8_off() applied to such a value does not
merely clear the flag: it re-encodes the byte content, producing a
doubly-encoded UTF-8 string, which is what reaches the browser.

The _utf8_off() call was introduced by upstream PR #134 (2017) to fix
mojibake with Perl 5.22+. On Perl 5.40.x its effect is reversed and it
now CAUSES the mojibake.

Evidence
--------
Formatting "%Y年" (year) for a fixed epoch, under LC_TIME=ja_JP.utf-8,
Perl 5.40.1. Correct UTF-8 for "年" is e5 b9 b4.

   POSIX::strftime result (no change):  is_utf8=1  年 -> e5 b9 b4
   after Encode::_utf8_off():           is_utf8=0  年 -> c3 a5 c2 b9 c2 b4   (double-encoded)
   after Encode::encode('UTF-8',$ret):  is_utf8=0  年 -> c3 a5 c2 b9 c2 b4   (double-encoded)
   after decode('UTF-8')+encode('UTF-8'): is_utf8=0 年 -> e5 b9 b4           (correct)

Only a decode/encode round-trip normalizes the value back to a plain
UTF-8 byte string on this Perl.

Fix
---
Replace the Encode::_utf8_off($ret) call with a decode/encode
round-trip. Patch against /usr/share/sympa/lib/Sympa/Language.pm:
--- a/usr/share/sympa/lib/Sympa/Language.pm
+++ b/usr/share/sympa/lib/Sympa/Language.pm
@@ -691,7 +691,12 @@
          POSIX::setlocale(POSIX::LC_TIME(), $self->{locale_time});
      }
      my $ret = POSIX::strftime($format, @args);
-    Encode::_utf8_off($ret);
+    # On Perl 5.40, POSIX::strftime() under a UTF-8 locale returns a string
+    # with the utf8 flag set but whose content is already UTF-8 bytes.
+    # Encode::_utf8_off() on such a string re-encodes the bytes (double
+    # encoding), garbling non-ASCII output. Normalize via a decode/encode
+    # round-trip so the result is always a plain UTF-8 byte string.
+    $ret = Encode::encode('UTF-8', Encode::decode('UTF-8', $ret));

          POSIX::setlocale(POSIX::LC_TIME(), $orig_locale);
      return $ret;

After applying this and restarting wwsympa.service, dates render
correctly in the web interface.

Scope of testing
----------------
Verified on Debian 13 trixie, sympa 6.2.76~dfsg-1, Perl 5.40.1, with
a UTF-8 locale (ja_JP). I have NOT tested other Perl versions or
non-UTF-8 locales; the interaction of the decode/encode round-trip with
those environments should be reviewed before wider application. This
likely warrants forwarding upstream (sympa-community/sympa), as the
affected code is upstream's.