aboutsummaryrefslogtreecommitdiff
path: root/locale
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2014-05-28 14:41:52 +0200
committerAllan McRae <allan@archlinux.org>2014-09-05 22:44:10 +1000
commit2da15d05c54738ed2c53aaf555c7cf51a9057844 (patch)
treeb8671cbcddb091a5060f7058828a88c12ae24b19 /locale
parent6ccc1c41f52f93548b5eb64d106219e287052472 (diff)
downloadglibc-2da15d05c54738ed2c53aaf555c7cf51a9057844.zip
glibc-2da15d05c54738ed2c53aaf555c7cf51a9057844.tar.gz
glibc-2da15d05c54738ed2c53aaf555c7cf51a9057844.tar.bz2
setlocale: Use the heap for the copy of the locale argument
This avoids alloca calls with potentially large arguments. (cherry picked from commit d183645616b0533b3acee28f1a95570bffbdf50f)
Diffstat (limited to 'locale')
-rw-r--r--locale/setlocale.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/locale/setlocale.c b/locale/setlocale.c
index b70fa6c..a4c5983 100644
--- a/locale/setlocale.c
+++ b/locale/setlocale.c
@@ -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 (__builtin_expect (strchr (locale, ';') != NULL, 0))
{
/* 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;
}