diff options
Diffstat (limited to 'lib/duplocale.c')
-rw-r--r-- | lib/duplocale.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/lib/duplocale.c b/lib/duplocale.c index eb7b8d365..430634dbe 100644 --- a/lib/duplocale.c +++ b/lib/duplocale.c @@ -1,5 +1,5 @@ /* Duplicate a locale object. - Copyright (C) 2009-2017 Free Software Foundation, Inc. + Copyright (C) 2009-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -12,7 +12,7 @@ GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ + along with this program. If not, see <https://www.gnu.org/licenses/>. */ /* Written by Bruno Haible <bruno@clisp.org>, 2007. */ @@ -32,9 +32,11 @@ locale_t rpl_duplocale (locale_t locale) { /* Work around crash in the duplocale function in glibc < 2.12. - See <http://sourceware.org/bugzilla/show_bug.cgi?id=10969>. + See <https://sourceware.org/bugzilla/show_bug.cgi?id=10969>. Also, on AIX 7.1, duplocale(LC_GLOBAL_LOCALE) returns (locale_t)0 with - errno set to EINVAL. */ + errno set to EINVAL. + Also, on NetBSD 7.0, duplocale(LC_GLOBAL_LOCALE) returns a locale that + corresponds to the C locale. */ if (locale == LC_GLOBAL_LOCALE) { /* Create a copy of the locale by fetching the name of each locale @@ -65,11 +67,17 @@ rpl_duplocale (locale_t locale) , { LC_IDENTIFICATION, LC_IDENTIFICATION_MASK } #endif }; - const char *base_name; + char base_name[SETLOCALE_NULL_MAX]; + int err; locale_t base_copy; unsigned int i; - base_name = setlocale (LC_CTYPE, NULL); + err = setlocale_null_r (LC_CTYPE, base_name, sizeof (base_name)); + if (err) + { + errno = err; + return NULL; + } base_copy = newlocale (LC_ALL_MASK, base_name, NULL); if (base_copy == NULL) return NULL; @@ -78,7 +86,14 @@ rpl_duplocale (locale_t locale) { int category = categories[i].cat; int category_mask = categories[i].mask; - const char *name = setlocale (category, NULL); + char name[SETLOCALE_NULL_MAX]; + + err = setlocale_null_r (category, name, sizeof (name)); + if (err) + { + errno = err; + return NULL; + } if (strcmp (name, base_name) != 0) { locale_t copy = newlocale (category_mask, name, base_copy); |