summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorschwarze <schwarze@openbsd.org>2018-03-29 16:34:25 +0000
committerschwarze <schwarze@openbsd.org>2018-03-29 16:34:25 +0000
commitf85ded84d67ce8e7f7589305fc9831335a4d3ad4 (patch)
treeb2dfd99372a7529594cdef7f46d2f2d2c787274e
parentAdd support for legacy binding used in device trees for Marvell devices for (diff)
downloadwireguard-openbsd-f85ded84d67ce8e7f7589305fc9831335a4d3ad4.tar.xz
wireguard-openbsd-f85ded84d67ce8e7f7589305fc9831335a4d3ad4.zip
Fix three bugs in setlocale(3):
1. setlocale(LC_ALL, "A"); setlocale(LC_CTYPE, "T"); setlocale(LC_ALL, NULL); must return "A/T/A/A/A/A", not "A". Fix this by always initializing the LC_ALL entry of newgl to "" in dupgl(). Reported by Karl Williamson <public at khwilliamson dot com> on bugs@, thanks! 2. Do not leak newgl when strdup(3) fails in setlocale(3). 3. For setlocale(LC_ALL, "C/C/fr_FR.UTF-8/C/C/C"); correctly set _GlobalRuneLocale; i found 2. and 3. while looking at the code. Feedback on a buggy earlier version and OK martijn@.
-rw-r--r--lib/libc/locale/setlocale.c12
-rw-r--r--regress/lib/libc/locale/setlocale/setlocale.c4
2 files changed, 9 insertions, 7 deletions
diff --git a/lib/libc/locale/setlocale.c b/lib/libc/locale/setlocale.c
index 7afc46ed497..78e5f0a5388 100644
--- a/lib/libc/locale/setlocale.c
+++ b/lib/libc/locale/setlocale.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: setlocale.c,v 1.27 2017/09/05 03:16:13 schwarze Exp $ */
+/* $OpenBSD: setlocale.c,v 1.28 2018/03/29 16:34:25 schwarze Exp $ */
/*
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
*
@@ -42,8 +42,8 @@ dupgl(char **oldgl)
if ((newgl = calloc(_LC_LAST, sizeof(*newgl))) == NULL)
return NULL;
for (ic = LC_ALL; ic < _LC_LAST; ic++) {
- if ((newgl[ic] = strdup(oldgl != NULL ?
- oldgl[ic] : ic == LC_ALL ? "" : "C")) == NULL) {
+ if ((newgl[ic] = strdup(ic == LC_ALL ? "" :
+ oldgl == NULL ? "C" : oldgl[ic])) == NULL) {
freegl(newgl);
return NULL;
}
@@ -92,8 +92,10 @@ setlocale(int category, const char *locname)
if (category == LC_ALL && strchr(locname, '/') != NULL) {
/* One value for each category. */
- if ((firstname = strdup(locname)) == NULL)
+ if ((firstname = strdup(locname)) == NULL) {
+ freegl(newgl);
return NULL;
+ }
nextname = firstname;
for (ic = 1; ic < _LC_LAST; ic++)
if (nextname == NULL || changegl(ic,
@@ -184,7 +186,7 @@ done:
global_locale = newgl;
if (category == LC_ALL || category == LC_CTYPE)
_GlobalRuneLocale =
- strchr(global_locname, '.') == NULL ?
+ strchr(newgl[LC_CTYPE], '.') == NULL ?
&_DefaultRuneLocale : _Utf8RuneLocale;
} else {
freegl(newgl);
diff --git a/regress/lib/libc/locale/setlocale/setlocale.c b/regress/lib/libc/locale/setlocale/setlocale.c
index f2a84275350..82245df5c5e 100644
--- a/regress/lib/libc/locale/setlocale/setlocale.c
+++ b/regress/lib/libc/locale/setlocale/setlocale.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: setlocale.c,v 1.3 2017/02/25 07:28:32 jsg Exp $ */
+/* $OpenBSD: setlocale.c,v 1.4 2018/03/29 16:34:25 schwarze Exp $ */
/*
* Copyright (c) 2015 Sebastien Marie <semarie@openbsd.org>
*
@@ -75,7 +75,6 @@ main(int argc, char *argv[])
/* load from env */
/* NOTE: we don't support non-C locales for some categories */
- /*test_setlocale("fr_FR.UTF-8", LC_ALL, "");*/ /* set */
test_setlocale("fr_FR.UTF-8", LC_CTYPE, ""); /* set */
test_setlocale("fr_FR.UTF-8", LC_MESSAGES, ""); /* set */
test_MB_CUR_MAX(4);
@@ -113,6 +112,7 @@ main(int argc, char *argv[])
test_setlocale("C", LC_ALL, "C"); /* reset */
test_setlocale("invalid.UTF-8", LC_CTYPE, "invalid.UTF-8"); /* set */
test_setlocale("invalid.UTF-8", LC_CTYPE, NULL);
+ test_setlocale("C/invalid.UTF-8/C/C/C/C", LC_ALL, NULL);
test_MB_CUR_MAX(4);
/* with invalid codeset (is an error) */