This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
locale.c: Handle and edge case
authorKarl Williamson <khw@cpan.org>
Fri, 16 Mar 2018 19:53:48 +0000 (13:53 -0600)
committerKarl Williamson <khw@cpan.org>
Fri, 16 Mar 2018 20:09:42 +0000 (14:09 -0600)
setlocale(LC_ALL, "LC_foo=bar; LC_baz=gah") is legal.  Any categories
omitted in the string are set to "C".  Prior to this commit the omitted
categories were unchanged

locale.c
t/run/locale.t

index cfbc056..7a0cd74 100644 (file)
--- a/locale.c
+++ b/locale.c
@@ -910,6 +910,7 @@ S_emulate_setlocale(const int category,
          * other platforms do it differently, so we have to handle all cases
          * ourselves */
 
+        unsigned int i;
         const char * s = locale;
         const char * e = locale + strlen(locale);
         const char * p = s;
@@ -917,8 +918,17 @@ S_emulate_setlocale(const int category,
         const char * name_start;
         const char * name_end;
 
+        /* If the string that gives what to set doesn't include all categories,
+         * the omitted ones get set to "C".  To get this behavior, first set
+         * all the individual categories to "C", and override the furnished
+         * ones below */
+        for (i = 0; i < LC_ALL_INDEX; i++) {
+            if (! emulate_setlocale(categories[i], "C", i, TRUE)) {
+                return NULL;
+            }
+        }
+
         while (s < e) {
-            unsigned int i;
 
             /* Parse through the category */
             while (isWORDCHAR(*p)) {
index b8778f1..9efac0b 100644 (file)
@@ -434,7 +434,9 @@ SKIP: {
     my $valid_string = "";
     my $invalid_string = "";
 
-    foreach my $category (@valid_categories) {
+    # Deliberately don't include all categories, so as to test this situation
+    for my $i (0 .. @valid_categories - 2) {
+        my $category = $valid_categories[$i];
         if ($category ne "LC_ALL") {
             $invalid_string .= ";" if $invalid_string ne "";
             $invalid_string .= "$category=foo_BAR";