setlocale: Use the heap for the copy of the locale argument
authorFlorian Weimer <fweimer@redhat.com>
Wed, 28 May 2014 12:41:52 +0000 (14:41 +0200)
committerFlorian Weimer <fweimer@redhat.com>
Thu, 10 Jul 2014 14:29:34 +0000 (16:29 +0200)
This avoids alloca calls with potentially large arguments.

ChangeLog
locale/setlocale.c

index a1232aa..5767e5c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2014-07-02  Florian Weimer  <fweimer@redhat.com>
+
+       * locale/setlocale.c (setlocale): Use strdup for allocating
+       composite name copy.
+
 2014-07-10  Siddhesh Poyarekar  <siddhesh@redhat.com>
 
        Sync up with gnulib.
index 9458468..6455b8b 100644 (file)
@@ -272,6 +272,8 @@ setlocale (int category, const char *locale)
         of entries of the form `CATEGORY=VALUE'.  */
       const char *newnames[__LC_LAST];
       struct __locale_data *newdata[__LC_LAST];
+      /* Copy of the locale argument, for in-place splitting.  */
+      char *locale_copy = NULL;
 
       /* Set all name pointers to the argument name.  */
       for (category = 0; category < __LC_LAST; ++category)
@@ -281,7 +283,13 @@ setlocale (int category, const char *locale)
       if (__glibc_unlikely (strchr (locale, ';') != NULL))
        {
          /* This is a composite name.  Make a copy and split it up.  */
-         char *np = strdupa (locale);
+         locale_copy = strdup (locale);
+         if (__glibc_unlikely (locale_copy == NULL))
+           {
+             __libc_rwlock_unlock (__libc_setlocale_lock);
+             return NULL;
+           }
+         char *np = locale_copy;
          char *cp;
          int cnt;
 
@@ -299,6 +307,7 @@ setlocale (int category, const char *locale)
                {
                error_return:
                  __libc_rwlock_unlock (__libc_setlocale_lock);
+                 free (locale_copy);
 
                  /* Bogus category name.  */
                  ERROR_RETURN;
@@ -391,8 +400,9 @@ setlocale (int category, const char *locale)
       /* Critical section left.  */
       __libc_rwlock_unlock (__libc_setlocale_lock);
 
-      /* Free the resources (the locale path variable).  */
+      /* Free the resources.  */
       free (locale_path);
+      free (locale_copy);
 
       return composite;
     }