diff options
author | David Chisnall <theraven@FreeBSD.org> | 2014-04-02 11:10:46 +0000 |
---|---|---|
committer | David Chisnall <theraven@FreeBSD.org> | 2014-04-02 11:10:46 +0000 |
commit | 8d07b7deffbddac47e9ad5f422f0bf3c2690e748 (patch) | |
tree | abc10866a5d9b37cae933eaf2387e6115c5ea89b /lib | |
parent | 07a5254736f66d843153688f71a7469755373968 (diff) | |
download | src-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.c | 2 | ||||
-rw-r--r-- | lib/libc/locale/xlocale.c | 16 |
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); |