summaryrefslogtreecommitdiff
path: root/lib/libc/locale
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@cvs.openbsd.org>2019-03-29 12:34:45 +0000
committerIngo Schwarze <schwarze@cvs.openbsd.org>2019-03-29 12:34:45 +0000
commitb948411757415ff9b6d54fd0d422f0d9261f95da (patch)
tree8cae7f7a257fbac341ecb7143b8e532d46b1269a /lib/libc/locale
parent42b8240b6f14ba76de2c16e93f20c1c588d56b7e (diff)
Copy categories outside "mask" from "oldloc" to the new locale object.
While POSIX appears to allow the old behaviour of ignoring "oldloc", Ted and Karl convinced me that is a bug in the spec and the Austin group almost certainly intended to require the new behaviour. Anyway, compatibility strongly suggests the new behaviour because most (or maybe even all?) other systems do not ignore "oldloc", and some software appears to depend on the copying from "oldloc" to the new locale. Issue analyzed and reported by Karl Williamson <public at khwilliamson dot com> with support from the Perl 5 community. This final diff is similar to two earlier diffs from Ted, but handles invalid input in a mode robust way. OK tedu@.
Diffstat (limited to 'lib/libc/locale')
-rw-r--r--lib/libc/locale/newlocale.343
-rw-r--r--lib/libc/locale/newlocale.c7
2 files changed, 31 insertions, 19 deletions
diff --git a/lib/libc/locale/newlocale.3 b/lib/libc/locale/newlocale.3
index 7e23b527e25..a9895a07e64 100644
--- a/lib/libc/locale/newlocale.3
+++ b/lib/libc/locale/newlocale.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: newlocale.3,v 1.1 2017/09/05 03:16:13 schwarze Exp $
+.\" $OpenBSD: newlocale.3,v 1.2 2019/03/29 12:34:44 schwarze Exp $
.\"
.\" Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: September 5 2017 $
+.Dd $Mdocdate: March 29 2019 $
.Dt NEWLOCALE 3
.Os
.Sh NAME
@@ -46,11 +46,23 @@ creates a new locale object for use with
and with many functions that accept
.Vt locale_t
arguments.
+Locale categories not contained in the
+.Fa mask
+are copied from
+.Fa oldloc
+to the new locale object, or from the
+.Qq C
+locale if
+.Fa oldloc
+is
+.Po Vt locale_t Pc Ns 0 .
.Pp
On
.Ox ,
+.Fa locname
+only affects the return value if
.Fa mask
-is only meaningful if it includes
+includes
.Dv LC_CTYPE_MASK ,
and
.Fa locname
@@ -60,18 +72,11 @@ or
.Qq POSIX ,
if it ends with
.Qq .UTF-8 ,
-or if it is an empty string; otherwise,
-.Fn newlocale
-always returns the C locale.
-.Pp
-On
-.Ox ,
-.Fn newlocale
-ignores
-.Fa oldloc ,
-and passing
-.Po Vt locale_t Pc Ns 0
-is recommended.
+or if it is an empty string.
+Other
+.Fa locname
+arguments have the same effect as
+.Qq C .
.Pp
The function
.Fn duplocale
@@ -159,3 +164,11 @@ These functions conform to
.Sh HISTORY
These functions have been available since
.Ox 6.2 .
+.Sh CAVEATS
+Calling
+.Fn newlocale
+with an
+.Fa oldloc
+argument of
+.Dv LC_GLOBAL_LOCALE
+results in undefined behaviour.
diff --git a/lib/libc/locale/newlocale.c b/lib/libc/locale/newlocale.c
index e8655a05dde..4617b64b67c 100644
--- a/lib/libc/locale/newlocale.c
+++ b/lib/libc/locale/newlocale.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: newlocale.c,v 1.1 2017/09/05 03:16:13 schwarze Exp $ */
+/* $OpenBSD: newlocale.c,v 1.2 2019/03/29 12:34:44 schwarze Exp $ */
/*
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
*
@@ -22,8 +22,7 @@
#include "rune.h"
locale_t
-newlocale(int mask, const char *locname,
- locale_t oldloc __attribute__((__unused__)))
+newlocale(int mask, const char *locname, locale_t oldloc)
{
int ic, flag;
@@ -45,7 +44,7 @@ newlocale(int mask, const char *locname,
/* Only character encoding has thread-specific effects. */
if ((mask & LC_CTYPE_MASK) == 0)
- return _LOCALE_C;
+ return oldloc == _LOCALE_UTF8 ? _LOCALE_UTF8 : _LOCALE_C;
/* The following may initialize UTF-8 for later use. */
if ((locname = _get_locname(LC_CTYPE, locname)) == NULL) {