svn commit: r264038 - head/lib/libc/locale
David Chisnall
theraven at FreeBSD.org
Wed Apr 2 11:10:47 UTC 2014
Author: theraven
Date: Wed Apr 2 11:10:46 2014
New Revision: 264038
URL: http://svnweb.freebsd.org/changeset/base/264038
Log:
Fix an issue where the locale and rune locale could become out of sync,
causing mb* functions (and similar) to be called with the wrong data
(possibly a null pointer, causing a crash).
PR: standards/188036
MFC after: 1 week
Modified:
head/lib/libc/locale/setrunelocale.c
head/lib/libc/locale/xlocale.c
Modified: head/lib/libc/locale/setrunelocale.c
==============================================================================
--- head/lib/libc/locale/setrunelocale.c Wed Apr 2 10:57:11 2014 (r264037)
+++ head/lib/libc/locale/setrunelocale.c Wed Apr 2 11:10:46 2014 (r264038)
@@ -202,6 +202,8 @@ __set_thread_rune_locale(locale_t loc)
if (loc == NULL) {
_ThreadRuneLocale = &_DefaultRuneLocale;
+ } else if (loc == LC_GLOBAL_LOCALE) {
+ _ThreadRuneLocale = 0;
} else {
_ThreadRuneLocale = XLOCALE_CTYPE(loc)->runes;
}
Modified: head/lib/libc/locale/xlocale.c
==============================================================================
--- head/lib/libc/locale/xlocale.c Wed Apr 2 10:57:11 2014 (r264037)
+++ head/lib/libc/locale/xlocale.c Wed Apr 2 11:10:46 2014 (r264038)
@@ -154,23 +154,24 @@ __get_locale(void)
static void
set_thread_locale(locale_t loc)
{
+ locale_t l = (loc == LC_GLOBAL_LOCALE) ? 0 : loc;
_once(&once_control, init_key);
- if (NULL != loc) {
- xlocale_retain((struct xlocale_refcounted*)loc);
+ if (NULL != l) {
+ xlocale_retain((struct xlocale_refcounted*)l);
}
locale_t old = pthread_getspecific(locale_info_key);
- if ((NULL != old) && (loc != old)) {
+ if ((NULL != old) && (l != old)) {
xlocale_release((struct xlocale_refcounted*)old);
}
if (fake_tls) {
- thread_local_locale = loc;
+ thread_local_locale = l;
} else {
- pthread_setspecific(locale_info_key, loc);
+ pthread_setspecific(locale_info_key, l);
}
#ifndef __NO_TLS
- __thread_locale = loc;
+ __thread_locale = l;
__set_thread_rune_locale(loc);
#endif
}
@@ -361,9 +362,6 @@ locale_t uselocale(locale_t loc)
{
locale_t old = get_thread_locale();
if (NULL != loc) {
- if (LC_GLOBAL_LOCALE == loc) {
- loc = NULL;
- }
set_thread_locale(loc);
}
return (old ? old : LC_GLOBAL_LOCALE);
More information about the svn-src-all
mailing list