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.