]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
locale: Avoid zero-length array in _nl_category_names [BZ #24962]
authorFlorian Weimer <fweimer@redhat.com>
Thu, 5 Sep 2019 20:16:58 +0000 (22:16 +0200)
committerFlorian Weimer <fweimer@redhat.com>
Thu, 5 Sep 2019 20:16:58 +0000 (22:16 +0200)
The union wrapper is unnecessary because C allows to read any object
as a sequence of chars.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
ChangeLog
intl/dcigettext.c
locale/findlocale.c
locale/loadlocale.c
locale/localeinfo.h
locale/newlocale.c
locale/setlocale.c

index 8fb6171ce5aabedb88fe9075e83dd1eefcde9c88..bd2f7add49cb5fcfefcf102065840c9d2dccf0aa 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2019-09-05  Florian Weimer  <fweimer@redhat.com>
+
+       [BZ #24962]
+       * locale/localeinfo.h (_nl_category_names): Remove union wrapper.
+       (_nl_category_names_get): New function.
+       * intl/dcigettext.c (category_to_name): Call it.
+       * locale/findlocale.c (_nl_find_locale): Likewise.
+       * intl/loadlocale.c (_nl_load_locale): Likewise.
+       * locale/newlocale.c (__newlocale): Likewise.
+       * locale/setlocale.c (_nl_category_names): Adjust definition.
+       (_nl_category_name_idxs): Likewise.
+       (new_composite_name): Call _nl_category_names_get.
+       (setlocale): Likewise.
+
 2019-09-05  Gabriel F. T. Gomes  <gabrielftg@linux.ibm.com>
 
        * math/bits/mathcalls.h (totalorder, totalordermag): Replace
index 4df93e2a8e3cc2a7b941f12e5f1aa358f184cf43..11f3749457b253e44bfabe461d95fab2eb3b4fe5 100644 (file)
@@ -360,8 +360,7 @@ static const char *guess_category_value (int category,
 
 #ifdef _LIBC
 # include "../locale/localeinfo.h"
-# define category_to_name(category) \
-  _nl_category_names.str + _nl_category_name_idxs[category]
+# define category_to_name(category) _nl_category_names_get (category)
 #else
 static const char *category_to_name (int category);
 #endif
index 9af605bd649447a7a7418d5da9569be9c9b59912..28b0226265180d1fdc3d1f9870517be5580ac43b 100644 (file)
@@ -118,8 +118,7 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len,
         variables.  */
       cloc_name = getenv ("LC_ALL");
       if (!name_present (cloc_name))
-       cloc_name = getenv (_nl_category_names.str
-                           + _nl_category_name_idxs[category]);
+       cloc_name = getenv (_nl_category_names_get (category));
       if (!name_present (cloc_name))
        cloc_name = getenv ("LANG");
       if (!name_present (cloc_name))
@@ -207,8 +206,7 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len,
                                    locale_path, locale_path_len, mask,
                                    language, territory, codeset,
                                    normalized_codeset, modifier,
-                                   _nl_category_names.str
-                                   + _nl_category_name_idxs[category], 0);
+                                   _nl_category_names_get (category), 0);
 
   if (locale_file == NULL)
     {
@@ -218,8 +216,7 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len,
                                        locale_path, locale_path_len, mask,
                                        language, territory, codeset,
                                        normalized_codeset, modifier,
-                                       _nl_category_names.str
-                                       + _nl_category_name_idxs[category], 1);
+                                       _nl_category_names_get (category), 1);
       if (locale_file == NULL)
        /* This means we are out of core.  */
        return NULL;
index 571c94e1de5b1655e16b410ccaf0016eec6a1509..ff578f641621828ed970941834ade7d49e153f50 100644 (file)
@@ -199,8 +199,7 @@ _nl_load_locale (struct loaded_l10nfile *file, int category)
       newp = (char *) alloca (filenamelen
                              + 5 + _nl_category_name_sizes[category] + 1);
       __mempcpy (__mempcpy (__mempcpy (newp, file->filename, filenamelen),
-                           "/SYS_", 5),
-                _nl_category_names.str + _nl_category_name_idxs[category],
+                           "/SYS_", 5), _nl_category_names_get (category),
                 _nl_category_name_sizes[category] + 1);
 
       fd = __open_nocancel (newp, O_RDONLY | O_CLOEXEC);
index 7c1cc3eecbfaa7c536f12312271987fa743f1b8a..0e2a0d7e49322c20658601c7d64440d73b1a8bc0 100644 (file)
@@ -183,23 +183,29 @@ enum
 #define _ISCTYPE(c, desc) \
   (((((const uint32_t *) (desc)) - 8)[(c) >> 5] >> ((c) & 0x1f)) & 1)
 
-/* Category name handling variables.  */
+/* Category name handling variables.  Concatenate all the strings in a
+   single object to minimize relocations.  Individual strings can be
+   accessed using _nl_category_names.  */
 #define CATNAMEMF(line) CATNAMEMF1 (line)
 #define CATNAMEMF1(line) str##line
-extern const union catnamestr_t
+extern const struct catnamestr_t
 {
-  struct
-  {
 #define DEFINE_CATEGORY(category, category_name, items, a) \
-    char CATNAMEMF (__LINE__)[sizeof (category_name)];
+  char CATNAMEMF (__LINE__)[sizeof (category_name)];
 #include "categories.def"
 #undef DEFINE_CATEGORY
-  };
-  char str[0];
 } _nl_category_names attribute_hidden;
 extern const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden;
 extern const uint8_t _nl_category_name_sizes[__LC_LAST] attribute_hidden;
 
+/* Return the name of the category INDEX, which must be nonnegative
+   and less than _LC_LAST.  */
+static inline const char *
+_nl_category_names_get (int index)
+{
+  return (const char *) &_nl_category_names + _nl_category_name_idxs[index];
+}
+
 /* Name of the standard locales.  */
 extern const char _nl_C_name[] attribute_hidden;
 extern const char _nl_POSIX_name[] attribute_hidden;
index 8c5960a45ddb98e3043aadeacf1c43474d6b0842..561244245b4c4d4e4aaffdc9f180e92b6a200dea 100644 (file)
@@ -131,8 +131,7 @@ __newlocale (int category_mask, const char *locale, locale_t base)
          for (cnt = 0; cnt < __LC_LAST; ++cnt)
            if (cnt != LC_ALL
                && (size_t) (cp - np) == _nl_category_name_sizes[cnt]
-               && memcmp (np, (_nl_category_names.str
-                               + _nl_category_name_idxs[cnt]), cp - np) == 0)
+               && memcmp (np, (_nl_category_names_get (cnt)), cp - np) == 0)
              break;
 
          if (cnt == __LC_LAST)
index 9bd35454b9346ec79b53675ef01b8d5eaede53ad..264a1ecba78b40abaab4ca9dce2e6cbca6d72774 100644 (file)
@@ -65,20 +65,18 @@ static char *const _nl_current_used[] =
 
 
 /* Define an array of category names (also the environment variable names).  */
-const union catnamestr_t _nl_category_names attribute_hidden =
+const struct catnamestr_t _nl_category_names attribute_hidden =
   {
-    {
 #define DEFINE_CATEGORY(category, category_name, items, a) \
-      category_name,
+    category_name,
 #include "categories.def"
 #undef DEFINE_CATEGORY
-    }
   };
 
 const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden =
   {
 #define DEFINE_CATEGORY(category, category_name, items, a) \
-    [category] = offsetof (union catnamestr_t, CATNAMEMF (__LINE__)),
+    [category] = offsetof (struct catnamestr_t, CATNAMEMF (__LINE__)),
 #include "categories.def"
 #undef DEFINE_CATEGORY
   };
@@ -180,7 +178,7 @@ new_composite_name (int category, const char *newnames[__LC_LAST])
        const char *name = (category == LC_ALL ? newnames[i]
                            : category == i ? newnames[0]
                            : _nl_global_locale.__names[i]);
-       p = __stpcpy (p, _nl_category_names.str + _nl_category_name_idxs[i]);
+       p = __stpcpy (p, _nl_category_names_get (i));
        *p++ = '=';
        p = __stpcpy (p, name);
        *p++ = ';';
@@ -298,8 +296,7 @@ setlocale (int category, const char *locale)
              for (cnt = 0; cnt < __LC_LAST; ++cnt)
                if (cnt != LC_ALL
                    && (size_t) (cp - np) == _nl_category_name_sizes[cnt]
-                   && (memcmp (np, (_nl_category_names.str
-                                    + _nl_category_name_idxs[cnt]), cp - np)
+                   && (memcmp (np, (_nl_category_names_get (cnt)), cp - np)
                        == 0))
                  break;