From 2935c197ac4c1c48a02fd3c107ffdcdcda54b99a Mon Sep 17 00:00:00 2001 From: Karl Williamson Date: Wed, 21 Dec 2022 13:24:28 -0700 Subject: Fix mojibake in POSIX::strftime() Some platforms require LC_CTYPE and LC_TIME to be the same. This toggles LC_CTYPE if necessary. --- locale.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'locale.c') diff --git a/locale.c b/locale.c index 073897a25a..5b9ca50b3b 100644 --- a/locale.c +++ b/locale.c @@ -4866,6 +4866,11 @@ and LC_TIME are not the same locale. # ifdef HAS_TM_TM_ZONE mytm.tm_zone = mytm2.tm_zone; # endif +#endif +#if defined(USE_LOCALE_CTYPE) && defined(USE_LOCALE_TIME) + + const char * orig_CTYPE_LOCALE = toggle_locale_c(LC_CTYPE, + querylocale_c(LC_TIME)); #endif /* Guess an initial size for the returned string based on an expansion @@ -4892,7 +4897,7 @@ and LC_TIME are not the same locale. * indicates we have at least one byte of spare space (which will be * used for the terminating NUL). */ if (inRANGE(len, 1, bufsize - 1)) { - return buf; + goto strftime_success; } /* There are several possible reasons for a 0 return code for a @@ -4916,7 +4921,7 @@ and LC_TIME are not the same locale. if (strEQ(fmt, "%p")) { Renew(buf, 1, char); *buf = '\0'; - return buf; + goto strftime_success; } /* The other reason is that the format string is malformed. Probably it is @@ -4924,6 +4929,15 @@ and LC_TIME are not the same locale. Safefree(buf); return NULL; + strftime_success: + +#if defined(USE_LOCALE_CTYPE) && defined(USE_LOCALE_TIME) + + restore_toggled_locale_c(LC_CTYPE, orig_CTYPE_LOCALE); + +#endif + return buf; + #else Perl_croak(aTHX_ "panic: no strftime"); return NULL; -- cgit v1.2.1