summaryrefslogtreecommitdiff
path: root/locale.c
diff options
context:
space:
mode:
authorKarl Williamson <khw@cpan.org>2022-12-21 13:24:28 -0700
committerKarl Williamson <khw@cpan.org>2023-01-05 19:57:29 -0700
commit2935c197ac4c1c48a02fd3c107ffdcdcda54b99a (patch)
tree9fa7d2452442223b02dba9f49e93b8d9f0239037 /locale.c
parentfdfa975e4ba4d1357e4f528b24e4ef24b001a6b3 (diff)
downloadperl-2935c197ac4c1c48a02fd3c107ffdcdcda54b99a.tar.gz
Fix mojibake in POSIX::strftime()
Some platforms require LC_CTYPE and LC_TIME to be the same. This toggles LC_CTYPE if necessary.
Diffstat (limited to 'locale.c')
-rw-r--r--locale.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/locale.c b/locale.c
index 073897a25a..5b9ca50b3b 100644
--- a/locale.c
+++ b/locale.c
@@ -4867,6 +4867,11 @@ and LC_TIME are not the same locale.
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
* factor of the input format, but with a minimum that should handle most
@@ -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;