This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Hi! Current setlocale implementation only stores copy of user provided string if it is setting LC_ALL, otherwise it would store into _nl_current_names second argument of setlocale directly (unless it was converted into _nl_C_name). But user is allowed to do anything with that pointer after return from setlocale, including freeing it, so we must make a copy. Example of code which is fixed by this patch: #include <locale.h> #include <string.h> int main() { char q[10]; setlocale(LC_ALL, ""); strcpy(q, "de_DE"); setlocale(LC_NUMERIC, q); strcpy(q, "xx_XX"); printf ("%s\n", setlocale(LC_NUMERIC, NULL)); exit (0); } Without this patch it prints xx_XX while with this patch it correctly prints de_DE. 2000-11-30 Jakub Jelinek <jakub@redhat.com> * setlocale.c (setname): Free for all categories, not just LC_ALL. (setlocale): Store a copy of string passed by user, not the string itself. --- libc/setlocale.c.jj Mon Nov 20 13:48:11 2000 +++ libc/setlocale.c Thu Nov 30 13:57:06 2000 @@ -194,7 +194,7 @@ setname (int category, const char *name) if (_nl_current_names[category] == name) return; - if (category == LC_ALL && _nl_current_names[category] != _nl_C_name) + if (_nl_current_names[category] != _nl_C_name) free ((char *) _nl_current_names[category]); _nl_current_names[category] = name; @@ -322,6 +322,14 @@ setlocale (int category, const char *loc control over the usage. So we mark it as un-deletable. */ if (newdata[category]->usage_count != UNDELETABLE) newdata[category]->usage_count = UNDELETABLE; + + /* Make a copy of locale name. */ + if (newnames[category] != _nl_C_name) + { + newnames[category] = strdup (newnames[category]); + if (newnames[category] == NULL) + break; + } } /* Create new composite name. */ @@ -342,6 +350,10 @@ setlocale (int category, const char *loc functions know about this. */ ++_nl_msg_cat_cntr; } + else + for (++category; category < __LC_LAST; ++category) + if (category != LC_ALL && newnames[category] != _nl_C_name) + free ((char *) newnames[category]); /* Critical section left. */ __libc_lock_unlock (__libc_setlocale_lock); @@ -376,10 +388,21 @@ setlocale (int category, const char *loc newdata->usage_count = UNDELETABLE; } + /* Make a copy of locale name. */ + if (newname[0] != _nl_C_name) + { + newname[0] = strdup (newname[0]); + if (newname[0] == NULL) + goto abort_single; + } + /* Create new composite name. */ composite = new_composite_name (category, newname); if (composite == NULL) { + if (newname[0] != _nl_C_name) + free ((char *) newname[0]); + /* Say that we don't have any data loaded. */ abort_single: newname[0] = NULL; Jakub
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |