Print this page
3154 Nonconforming tolower and toupper with UTF-8 locales
Reviewed by: Garrett D'Amore <garrett.damore@gmail.com>

@@ -209,10 +209,11 @@
         _FileRuneLocale rl;
         ctype_node_t    *ctn, *last_ct, *last_lo, *last_up;
         _FileRuneEntry  *ct = NULL;
         _FileRuneEntry  *lo = NULL;
         _FileRuneEntry  *up = NULL;
+        wchar_t         wc;
 
         (void) memset(&rl, 0, sizeof (rl));
         last_ct = NULL;
         last_lo = NULL;
         last_up = NULL;

@@ -221,15 +222,23 @@
                 return;
 
         (void) memcpy(rl.magic, _FILE_RUNE_MAGIC_1, 8);
         (void) strncpy(rl.encoding, get_wide_encoding(), sizeof (rl.encoding));
 
-        for (ctn = avl_first(&ctypes); ctn; ctn = AVL_NEXT(&ctypes, ctn)) {
+        /*
+         * Initialize the identity map.
+         */
+        for (wc = 0; (unsigned)wc < _CACHED_RUNES; wc++) {
+                rl.maplower[wc] = wc;
+                rl.mapupper[wc] = wc;
+        }
 
-                wchar_t wc = ctn->wc;
+        for (ctn = avl_first(&ctypes); ctn; ctn = AVL_NEXT(&ctypes, ctn)) {
                 int conflict = 0;
 
+                wc = ctn->wc;
+
                 /*
                  * POSIX requires certain portable characters have
                  * certain types.  Add them if they are missing.
                  */
                 if ((wc >= 1) && (wc <= 127)) {

@@ -303,12 +312,14 @@
                  * optimization.  Note that if we have not defined the
                  * upper/lower case, then we identity map it.
                  */
                 if ((unsigned)wc < _CACHED_RUNES) {
                         rl.runetype[wc] = ctn->ctype;
-                        rl.maplower[wc] = ctn->tolower ? ctn->tolower : wc;
-                        rl.mapupper[wc] = ctn->toupper ? ctn->toupper : wc;
+                        if (ctn->tolower)
+                                rl.maplower[wc] = ctn->tolower;
+                        if (ctn->toupper)
+                                rl.mapupper[wc] = ctn->toupper;
                         continue;
                 }
 
                 if ((last_ct != NULL) && (last_ct->ctype == ctn->ctype)) {
                         ct[rl.runetype_ext_nranges-1].max = wc;