From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25326 invoked by alias); 20 May 2011 08:01:04 -0000 Received: (qmail 25314 invoked by uid 22791); 20 May 2011 08:01:02 -0000 X-SWARE-Spam-Status: No, hits=-2.8 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from localhost (HELO sourceware.org) (127.0.0.1) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 20 May 2011 08:00:49 +0000 From: "bug_rh at spam dot wizbit.be" To: glibc-bugs@sources.redhat.com Subject: [Bug localedata/12788] New: [PATCH] setlocale sets the locale of LC_ALL incorrect to 'C' in some cases (/when LC_CTYPE is used) X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: glibc X-Bugzilla-Component: localedata X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: bug_rh at spam dot wizbit.be X-Bugzilla-Status: NEW X-Bugzilla-Priority: P2 X-Bugzilla-Assigned-To: libc-locales at sources dot redhat.com X-Bugzilla-Target-Milestone: --- X-Bugzilla-Changed-Fields: Message-ID: X-Bugzilla-URL: http://sourceware.org/bugzilla/ Auto-Submitted: auto-generated Content-Type: text/plain; charset="UTF-8" MIME-Version: 1.0 Date: Fri, 20 May 2011 08:01:00 -0000 Mailing-List: contact glibc-bugs-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: glibc-bugs-owner@sourceware.org X-SW-Source: 2011-05/txt/msg00206.txt.bz2 http://sourceware.org/bugzilla/show_bug.cgi?id=12788 Summary: [PATCH] setlocale sets the locale of LC_ALL incorrect to 'C' in some cases (/when LC_CTYPE is used) Product: glibc Version: unspecified Status: NEW Severity: normal Priority: P2 Component: localedata AssignedTo: libc-locales@sources.redhat.com ReportedBy: bug_rh@spam.wizbit.be Created attachment 5739 --> http://sourceware.org/bugzilla/attachment.cgi?id=5739 patch - update the condition in set_composite_name There is a bug in setlocale that can result in LC_ALL being incorrectly set to LC_ALL. Test case: $ cat bug-setlocale.c #include #include int main () { printf("setlocale(LC_ALL, \"\") = %s\n", setlocale(LC_ALL, "")); printf("setlocale(LC_CTYPE, \"\") = %s\n", setlocale(LC_CTYPE, "")); printf("setlocale(LC_ALL, NULL) = %s\n", setlocale(LC_ALL, NULL)); printf("setlocale(LC_NUMERIC, \"\") = %s\n", setlocale(LC_NUMERIC, "")); printf("setlocale(LC_ALL, NULL) = %s\n", setlocale(LC_ALL, NULL)); setlocale(LC_ALL, "C"); printf("setlocale(LC_ALL, NULL) = %s\n", setlocale(LC_ALL, NULL)); printf("setlocale(LC_CTYPE, NULL) = %s\n", setlocale(LC_CTYPE, NULL)); } Running it: $ env -i LC_CTYPE=en_US ./bug-setlocale setlocale(LC_ALL, "") = LC_CTYPE=en_US;LC_NUMERIC=C;LC_.... # => expected setlocale(LC_CTYPE, "") = en_US # => expected setlocale(LC_ALL, NULL) = LC_CTYPE=en_US;LC_NUMERIC=C;LC_... # => expected setlocale(LC_NUMERIC, "") = C # => expected setlocale(LC_ALL, NULL) = C # => not expected; expected value: LC_CTYPE=en_US;LC_NUMERIC=C;LC_... setlocale(LC_ALL, NULL) = C # => expected setlocale(LC_CTYPE, NULL) = en_US # => not expected; expected value: 'C' Important when running the test case: a) the locale en_US needs to be installed/needs to exists on the system b) only the environment variable LC_CTYPE should be set (LC_ALL, LANG, LC_COLLATE, LC_MESSAGES, LC_MONETARY, LC_NUMERIC, LC_TIME need to be unset) I traced the problem to the file locale/setlocale.c, function: new_composite_name, line: 150-160: for (i = 0; i < __LC_LAST; ++i) if (i != LC_ALL) { const char *name = (category == LC_ALL ? newnames[i] : category == i ? newnames[0] : _nl_global_locale.__names[i]); last_len = strlen (name); cumlen += _nl_category_name_sizes[i] + 1 + last_len + 1; if (i > 0 && same && strcmp (name, newnames[0]) != 0) same = 0; } The problem is the condition on line 158: the 'i > 0' is incorrect. The condition should be: ((category == LC_ALL && i > 0) || (category != LC_ALL && i != category)) The reasoning/the explanation (using the above test case): A) setlocale(LC_ALL, ""): This calls new_composite_name with category = 6 and newnames an array of 13 elements. For i = 0: name = newnames[0] => strcmp(name, newnames[0]) != 0 can be skipped For i = 1: name = newnames[1] => strcmp(name, newnames[1]) != 0 can not be skipped B) setlocale(LC_CTYPE, "") This calls new_composite_name with category = 0 and newnames an array of 1 element For i = 0: name = newnames[0] => strcmp(name, newnames[0]) != 0 can be skipped For i = 1: name = _nl_global_locale.__names[1] => strcmp(name, newnames[0]) != 0 can not be skipped C) setlocale(LC_NUMERIC, "") This calls new_composite_name with category = 1 and newnames an array of 1 element For i = 0: name = _nl_global_locale.__names[0] => strcmp(name, newnames[0]) != 0 can not be skipped For i = 1: name = newnames[0] => strcmp(name, newnames[0]) != 0 can be skipped ==> strcmp(name, newnames[0]) != 0 can only be skipped if: * category == LC_ALL and i == 0 * category != LC_ALL and i == category The bug was (I believe) introduced in commit 4b10dd6c1959577f57850ca427a94fe22b9f3299 (dated Tue, 31 Aug 1999 07:04:41 +0000 (07:04 +0000)) Attached is a patch which updates the condition. The output after the patch: $ env -i LC_CTYPE=en_US ./bug-setlocale setlocale(LC_ALL, "") = LC_CTYPE=en_US;LC_NUMERIC=C;LC_TIME=C;LC_COLLATE=C;LC_MONETARY=C;LC_MESSAGES=C;LC_PAPER=C;LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=C;LC_IDENTIFICATION=C setlocale(LC_CTYPE, "") = en_US setlocale(LC_ALL, NULL) = LC_CTYPE=en_US;LC_NUMERIC=C;LC_TIME=C;LC_COLLATE=C;LC_MONETARY=C;LC_MESSAGES=C;LC_PAPER=C;LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=C;LC_IDENTIFICATION=C setlocale(LC_NUMERIC, "") = C setlocale(LC_ALL, NULL) = LC_CTYPE=en_US;LC_NUMERIC=C;LC_TIME=C;LC_COLLATE=C;LC_MONETARY=C;LC_MESSAGES=C;LC_PAPER=C;LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=C;LC_IDENTIFICATION=C setlocale(LC_ALL, NULL) = C setlocale(LC_CTYPE, NULL) = C -- Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are on the CC list for the bug.