|
Message-Id: <4C4AEBC7-4344-4867-B8F6-F1A691F123E0@gmail.com> Date: Fri, 1 Apr 2016 20:47:01 -0400 From: Assaf Gordon <assafgordon@...il.com> To: musl@...ts.openwall.com Subject: Possible bug in setlocale upon invalid LC_ALL value Hello musl developers, I'm testing compilation of GNU coreutils on Alpine Linux 3.3.3 (linux kernel 4.1.20, musl-1.1.12-r3). I think I've encountered a problem in musl, where using setlocale with invalid locale name returns the invalid locale instead of a known locale. example: $ LC_ALL=missing ./myprogram If myprogram calls setlocale(LC_ALL,""), then musl sets the internal locale despite being invalid value. later, checking the locale for a specific category (e.g. LC_COLLATE) will return 'missing' instead of 'C' . The relevant POSIX clause is this: http://pubs.opengroup.org/onlinepubs/9699919799/functions/setlocale.html "[...] If the value of any of these environment variable searches yields a locale that is not supported (and non-null), setlocale() shall return a null pointer and the global locale shall not be changed." Below is a short C program demonstrating the issue, with example output from various OSes. comments welcomed, - assaf /* Test 'setlocale()' behaviour. compile: cc -o print-locale print-locale.c test: ./print-locale LC_ALL=C ./print-locale LC_ALL=missing ./print-locale */ #include <locale.h> #include <stdlib.h> #include <stdio.h> int main(void) { char* p = getenv("LC_ALL"); printf("LC_ALL env var = '%s'\n", p?p:"(NULL)"); p = setlocale(LC_ALL,""); printf("setlocale(LC_ALL,\"\") = '%s'\n", p?p:"(NULL)"); p = setlocale(LC_ALL,NULL); printf("LC_ALL from setlocale = '%s'\n", p?p:"(NULL)"); p = setlocale(LC_COLLATE,NULL); printf("LC_COLLATE from setlocale = '%s'\n", p?p:"(NULL)"); return 0; } ==== musl libc ======= $ ./print-locale LC_ALL env var = '(NULL)' setlocale(LC_ALL,"") = 'C.UTF-8;C;C;C;C;C' LC_ALL from setlocale = 'C.UTF-8;C;C;C;C;C' LC_COLLATE from setlocale = 'C' $ LC_ALL=c ./print-locale LC_ALL env var = 'C' setlocale(LC_ALL,"") = 'C;C;C;C;C;C' LC_ALL from setlocale = 'C;C;C;C;C;C' LC_COLLATE from setlocale = 'C' $ LC_ALL=missing ./print-locale LC_ALL env var = 'missing' setlocale(LC_ALL,"") = 'missing;missing;missing;missing;missing;missing' LC_ALL from setlocale = 'missing;missing;missing;missing;missing;missing' LC_COLLATE from setlocale = 'missing' ==== glibc (Ubuntu) ==== $ ./print-locale LC_ALL env var = '(NULL)' setlocale(LC_ALL,"") = 'en_US.UTF-8' LC_ALL from setlocale = 'en_US.UTF-8' LC_COLLATE from setlocale = 'en_US.UTF-8' $ LC_ALL=C ./print-locale LC_ALL env var = 'C' setlocale(LC_ALL,"") = 'C' LC_ALL from setlocale = 'C' LC_COLLATE from setlocale = 'C' $ LC_ALL=missing ./print-locale LC_ALL env var = 'missing' setlocale(LC_ALL,"") = '(NULL)' LC_ALL from setlocale = 'C' LC_COLLATE from setlocale = 'C' ==== FreeBSD 10.1 ==== $ ./print-locale LC_ALL env var = '(NULL)' setlocale(LC_ALL,"") = 'C' LC_ALL from setlocale = 'C' LC_COLLATE from setlocale = 'C' $ LC_ALL=C ./print-locale LC_ALL env var = 'C' setlocale(LC_ALL,"") = 'C' LC_ALL from setlocale = 'C' LC_COLLATE from setlocale = 'C' $ LC_ALL=missing ./print-locale LC_ALL env var = 'missing' setlocale(LC_ALL,"") = '(NULL)' LC_ALL from setlocale = 'C' LC_COLLATE from setlocale = 'C' ==== OpenBSD 5.8 ==== $ ./print-locale LC_ALL env var = '(NULL)' setlocale(LC_ALL,"") = 'C' LC_ALL from setlocale = 'C' LC_COLLATE from setlocale = 'C' $ LC_ALL=C ./print-locale LC_ALL env var = 'C' setlocale(LC_ALL,"") = 'C' LC_ALL from setlocale = 'C' LC_COLLATE from setlocale = 'C' $ LC_ALL=missing ./print-locale LC_ALL env var = 'missing' setlocale(LC_ALL,"") = 'C/missing/C/C/C/C' LC_ALL from setlocale = 'C/missing/C/C/C/C' LC_COLLATE from setlocale = 'C' ==== AIX 7 === $ ./print-locale LC_ALL env var = '(NULL)' setlocale(LC_ALL,"") = 'en_US en_US en_US en_US en_US en_US' LC_ALL from setlocale = 'en_US en_US en_US en_US en_US en_US' LC_COLLATE from setlocale = 'en_US' $ LC_ALL=C ./print-locale LC_ALL env var = 'C' setlocale(LC_ALL,"") = 'C C C C C C' LC_ALL from setlocale = 'C C C C C C' LC_COLLATE from setlocale = 'C' $ LC_ALL=missing ./print-locale LC_ALL env var = 'missing' setlocale(LC_ALL,"") = '(NULL)' LC_ALL from setlocale = 'C C C C C C' LC_COLLATE from setlocale = 'C'
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.