summaryrefslogtreecommitdiffstats
path: root/lib/libc/locale
diff options
context:
space:
mode:
authortheraven <theraven@FreeBSD.org>2012-06-11 14:02:02 +0000
committertheraven <theraven@FreeBSD.org>2012-06-11 14:02:02 +0000
commit1b6b7176ba276ada324f9e9140d3448f66c8738f (patch)
tree8c8b838fb575ea3e5cfa95a2d148bb2b935cc1ac /lib/libc/locale
parent1948616051a3a543041f0347326fef73815df200 (diff)
downloadFreeBSD-src-1b6b7176ba276ada324f9e9140d3448f66c8738f.zip
FreeBSD-src-1b6b7176ba276ada324f9e9140d3448f66c8738f.tar.gz
Fix a leak when setting the global character locale to "C" from something else.
Reported by: mm
Diffstat (limited to 'lib/libc/locale')
-rw-r--r--lib/libc/locale/setrunelocale.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/lib/libc/locale/setrunelocale.c b/lib/libc/locale/setrunelocale.c
index bc04e9e..f036bbc 100644
--- a/lib/libc/locale/setrunelocale.c
+++ b/lib/libc/locale/setrunelocale.c
@@ -89,6 +89,17 @@ const _RuneLocale *__getCurrentRuneLocale(void)
return XLOCALE_CTYPE(__get_locale())->runes;
}
+static void free_runes(_RuneLocale *rl)
+{
+ /* FIXME: The "EUC" check here is a hideous abstraction violation. */
+ if ((rl != &_DefaultRuneLocale) && (rl)) {
+ if (strcmp(rl->__encoding, "EUC") == 0) {
+ free(rl->__variable);
+ }
+ free(rl);
+ }
+}
+
static int
__setrunelocale(struct xlocale_ctype *l, const char *encoding)
{
@@ -102,6 +113,7 @@ __setrunelocale(struct xlocale_ctype *l, const char *encoding)
* The "C" and "POSIX" locale are always here.
*/
if (strcmp(encoding, "C") == 0 || strcmp(encoding, "POSIX") == 0) {
+ free_runes(saved.runes);
(void) _none_init(l, (_RuneLocale*)&_DefaultRuneLocale);
return (0);
}
@@ -153,13 +165,7 @@ __setrunelocale(struct xlocale_ctype *l, const char *encoding)
if (ret == 0) {
/* Free the old runes if it exists. */
- /* FIXME: The "EUC" check here is a hideous abstraction violation. */
- if ((saved.runes != &_DefaultRuneLocale) && (saved.runes)) {
- if (strcmp(saved.runes->__encoding, "EUC") == 0) {
- free(saved.runes->__variable);
- }
- free(saved.runes);
- }
+ free_runes(saved.runes);
} else {
/* Restore the saved version if this failed. */
memcpy(l, &saved, sizeof(struct xlocale_ctype));
OpenPOWER on IntegriCloud