aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDavid Chisnall <theraven@FreeBSD.org>2014-04-02 11:10:46 +0000
committerDavid Chisnall <theraven@FreeBSD.org>2014-04-02 11:10:46 +0000
commit8d07b7deffbddac47e9ad5f422f0bf3c2690e748 (patch)
treeabc10866a5d9b37cae933eaf2387e6115c5ea89b /lib
parent07a5254736f66d843153688f71a7469755373968 (diff)
downloadsrc-8d07b7deffbddac47e9ad5f422f0bf3c2690e748.tar.gz
src-8d07b7deffbddac47e9ad5f422f0bf3c2690e748.zip
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
Notes
Notes: svn path=/head/; revision=264038
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/locale/setrunelocale.c2
-rw-r--r--lib/libc/locale/xlocale.c16
2 files changed, 9 insertions, 9 deletions
diff --git a/lib/libc/locale/setrunelocale.c b/lib/libc/locale/setrunelocale.c
index 49e6f6e6548b..0a0943febb45 100644
--- a/lib/libc/locale/setrunelocale.c
+++ b/lib/libc/locale/setrunelocale.c
@@ -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;
}
diff --git a/lib/libc/locale/xlocale.c b/lib/libc/locale/xlocale.c
index e114bac74f2c..f9b7db107aec 100644
--- a/lib/libc/locale/xlocale.c
+++ b/lib/libc/locale/xlocale.c
@@ -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);