diff options
author | theraven <theraven@FreeBSD.org> | 2012-06-11 14:02:02 +0000 |
---|---|---|
committer | theraven <theraven@FreeBSD.org> | 2012-06-11 14:02:02 +0000 |
commit | 1b6b7176ba276ada324f9e9140d3448f66c8738f (patch) | |
tree | 8c8b838fb575ea3e5cfa95a2d148bb2b935cc1ac /lib/libc/locale | |
parent | 1948616051a3a543041f0347326fef73815df200 (diff) | |
download | FreeBSD-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.c | 20 |
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)); |