aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <pcarlini@suse.de>2003-10-16 17:24:07 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2003-10-16 17:24:07 +0000
commitf991b1d853560928299d8dea3885da56ad8048b6 (patch)
tree4980f05e99f727db30eb95c041e7c98bb689d201
parent968e3f935ba908bea6ff1348e033be77f652586d (diff)
downloadgcc-f991b1d853560928299d8dea3885da56ad8048b6.zip
gcc-f991b1d853560928299d8dea3885da56ad8048b6.tar.gz
gcc-f991b1d853560928299d8dea3885da56ad8048b6.tar.bz2
re PR libstdc++/12540 (Memory leak in locale::locale(const char*))
2003-10-16 Paolo Carlini <pcarlini@suse.de> PR libstdc++/12540 * config/locale/gnu/monetary_members.cc (moneypunct<wchar_t, true/false>::_M_initialize_moneypunct): Don't leak memory if new throws. * src/locale.cc (locale::locale(const char*)): In order not to leak memory in case new throws, use a basic_string type for __res too and avoid strdup. From-SVN: r72553
-rw-r--r--libstdc++-v3/ChangeLog10
-rw-r--r--libstdc++-v3/config/locale/gnu/monetary_members.cc196
-rw-r--r--libstdc++-v3/src/locale.cc15
3 files changed, 128 insertions, 93 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 6b73aee..c53f885 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,13 @@
+2003-10-16 Paolo Carlini <pcarlini@suse.de>
+
+ PR libstdc++/12540
+ * config/locale/gnu/monetary_members.cc
+ (moneypunct<wchar_t, true/false>::_M_initialize_moneypunct):
+ Don't leak memory if new throws.
+ * src/locale.cc (locale::locale(const char*)): In order not
+ to leak memory in case new throws, use a basic_string type
+ for __res too and avoid strdup.
+
2003-10-14 Jeff Bailey <jbailey@nisa.net>
PR libstdc++/12562
diff --git a/libstdc++-v3/config/locale/gnu/monetary_members.cc b/libstdc++-v3/config/locale/gnu/monetary_members.cc
index a22bdfe..0c03feb 100644
--- a/libstdc++-v3/config/locale/gnu/monetary_members.cc
+++ b/libstdc++-v3/config/locale/gnu/monetary_members.cc
@@ -379,47 +379,60 @@ namespace std
const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc);
const char* __ccurr = __nl_langinfo_l(__INT_CURR_SYMBOL, __cloc);
- mbstate_t __state;
- size_t __len = strlen(__cpossign);
- if (__len)
+ wchar_t* __wcs_ps = 0;
+ wchar_t* __wcs_ns = 0;
+ const char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc));
+ try
{
- ++__len;
- memset(&__state, 0, sizeof(mbstate_t));
- wchar_t* __wcs = new wchar_t[__len];
- mbsrtowcs(__wcs, &__cpossign, __len, &__state);
- _M_data->_M_positive_sign = __wcs;
+ mbstate_t __state;
+ size_t __len = strlen(__cpossign);
+ if (__len)
+ {
+ ++__len;
+ memset(&__state, 0, sizeof(mbstate_t));
+ __wcs_ps = new wchar_t[__len];
+ mbsrtowcs(__wcs_ps, &__cpossign, __len, &__state);
+ _M_data->_M_positive_sign = __wcs_ps;
+ }
+ else
+ _M_data->_M_positive_sign = L"";
+
+ __len = strlen(__cnegsign);
+ if (!__nposn)
+ _M_data->_M_negative_sign = L"()";
+ else if (__len)
+ {
+ ++__len;
+ memset(&__state, 0, sizeof(mbstate_t));
+ __wcs_ns = new wchar_t[__len];
+ mbsrtowcs(__wcs_ns, &__cnegsign, __len, &__state);
+ _M_data->_M_negative_sign = __wcs_ns;
+ }
+ else
+ _M_data->_M_negative_sign = L"";
+
+ // _Intl == true.
+ __len = strlen(__ccurr);
+ if (__len)
+ {
+ ++__len;
+ memset(&__state, 0, sizeof(mbstate_t));
+ wchar_t* __wcs = new wchar_t[__len];
+ mbsrtowcs(__wcs, &__ccurr, __len, &__state);
+ _M_data->_M_curr_symbol = __wcs;
+ }
+ else
+ _M_data->_M_curr_symbol = L"";
}
- else
- _M_data->_M_positive_sign = L"";
-
- char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc));
- __len = strlen(__cnegsign);
- if (!__nposn)
- _M_data->_M_negative_sign = L"()";
- else if (__len)
- {
- ++__len;
- memset(&__state, 0, sizeof(mbstate_t));
- wchar_t* __wcs = new wchar_t[__len];
- mbsrtowcs(__wcs, &__cnegsign, __len, &__state);
- _M_data->_M_negative_sign = __wcs;
- }
- else
- _M_data->_M_negative_sign = L"";
-
- // _Intl == true.
- __len = strlen(__ccurr);
- if (__len)
+ catch (...)
{
- ++__len;
- memset(&__state, 0, sizeof(mbstate_t));
- wchar_t* __wcs = new wchar_t[__len];
- mbsrtowcs(__wcs, &__ccurr, __len, &__state);
- _M_data->_M_curr_symbol = __wcs;
- }
- else
- _M_data->_M_curr_symbol = L"";
-
+ delete _M_data;
+ _M_data = 0;
+ delete __wcs_ps;
+ delete __wcs_ns;
+ __throw_exception_again;
+ }
+
_M_data->_M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS,
__cloc));
char __pprecedes = *(__nl_langinfo_l(__INT_P_CS_PRECEDES, __cloc));
@@ -442,18 +455,18 @@ namespace std
}
template<>
- void
- moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale __cloc,
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
- const char*)
+ void
+ moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale __cloc,
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
+ const char*)
#else
- const char* __name)
+ const char* __name)
#endif
- {
- if (!_M_data)
- _M_data = new __moneypunct_cache<wchar_t>;
+ {
+ if (!_M_data)
+ _M_data = new __moneypunct_cache<wchar_t>;
- if (!__cloc)
+ if (!__cloc)
{
// "C" locale
_M_data->_M_decimal_point = L'.';
@@ -489,47 +502,60 @@ namespace std
const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc);
const char* __ccurr = __nl_langinfo_l(__CURRENCY_SYMBOL, __cloc);
- mbstate_t __state;
- size_t __len;
- __len = strlen(__cpossign);
- if (__len)
- {
- ++__len;
- memset(&__state, 0, sizeof(mbstate_t));
- wchar_t* __wcs = new wchar_t[__len];
- mbsrtowcs(__wcs, &__cpossign, __len, &__state);
- _M_data->_M_positive_sign = __wcs;
- }
- else
- _M_data->_M_positive_sign = L"";
-
- char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc));
- __len = strlen(__cnegsign);
- if (!__nposn)
- _M_data->_M_negative_sign = L"()";
- else if (__len)
- {
- ++__len;
- memset(&__state, 0, sizeof(mbstate_t));
- wchar_t* __wcs = new wchar_t[__len];
- mbsrtowcs(__wcs, &__cnegsign, __len, &__state);
- _M_data->_M_negative_sign = __wcs;
+ wchar_t* __wcs_ps = 0;
+ wchar_t* __wcs_ns = 0;
+ const char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc));
+ try
+ {
+ mbstate_t __state;
+ size_t __len;
+ __len = strlen(__cpossign);
+ if (__len)
+ {
+ ++__len;
+ memset(&__state, 0, sizeof(mbstate_t));
+ __wcs_ps = new wchar_t[__len];
+ mbsrtowcs(__wcs_ps, &__cpossign, __len, &__state);
+ _M_data->_M_positive_sign = __wcs_ps;
+ }
+ else
+ _M_data->_M_positive_sign = L"";
+
+ __len = strlen(__cnegsign);
+ if (!__nposn)
+ _M_data->_M_negative_sign = L"()";
+ else if (__len)
+ {
+ ++__len;
+ memset(&__state, 0, sizeof(mbstate_t));
+ __wcs_ns = new wchar_t[__len];
+ mbsrtowcs(__wcs_ns, &__cnegsign, __len, &__state);
+ _M_data->_M_negative_sign = __wcs_ns;
+ }
+ else
+ _M_data->_M_negative_sign = L"";
+
+ // _Intl == true.
+ __len = strlen(__ccurr);
+ if (__len)
+ {
+ ++__len;
+ memset(&__state, 0, sizeof(mbstate_t));
+ wchar_t* __wcs = new wchar_t[__len];
+ mbsrtowcs(__wcs, &__ccurr, __len, &__state);
+ _M_data->_M_curr_symbol = __wcs;
+ }
+ else
+ _M_data->_M_curr_symbol = L"";
}
- else
- _M_data->_M_negative_sign = L"";
-
- // _Intl == true.
- __len = strlen(__ccurr);
- if (__len)
+ catch (...)
{
- ++__len;
- memset(&__state, 0, sizeof(mbstate_t));
- wchar_t* __wcs = new wchar_t[__len];
- mbsrtowcs(__wcs, &__ccurr, __len, &__state);
- _M_data->_M_curr_symbol = __wcs;
+ delete _M_data;
+ _M_data = 0;
+ delete __wcs_ps;
+ delete __wcs_ns;
+ __throw_exception_again;
}
- else
- _M_data->_M_curr_symbol = L"";
_M_data->_M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS, __cloc));
char __pprecedes = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc));
diff --git a/libstdc++-v3/src/locale.cc b/libstdc++-v3/src/locale.cc
index baa5a41..12f77e1 100644
--- a/libstdc++-v3/src/locale.cc
+++ b/libstdc++-v3/src/locale.cc
@@ -208,20 +208,20 @@ namespace std
}
else
{
- char* __res;
+ string __res;
// LANG may set a default different from "C".
char* __env = std::getenv("LANG");
if (!__env || std::strcmp(__env, "") == 0
|| std::strcmp(__env, "C") == 0
|| std::strcmp(__env, "POSIX") == 0)
- __res = strdup("C");
+ __res = "C";
else
- __res = strdup(__env);
+ __res = __env;
// Scan the categories looking for the first one
// different from LANG.
size_t __i = 0;
- if (std::strcmp(__res, "C") == 0)
+ if (std::strcmp(__res.c_str(), "C") == 0)
for (; __i < _S_categories_size; ++__i)
{
__env = std::getenv(_S_categories[__i]);
@@ -235,7 +235,7 @@ namespace std
{
__env = std::getenv(_S_categories[__i]);
if (__env && std::strcmp(__env, "") != 0
- && std::strcmp(__env, __res) != 0)
+ && std::strcmp(__env, __res.c_str()) != 0)
break;
}
@@ -285,11 +285,10 @@ namespace std
}
// ... otherwise either an additional instance of
// the "C" locale or LANG.
- else if (std::strcmp(__res, "C") == 0)
+ else if (std::strcmp(__res.c_str(), "C") == 0)
(_M_impl = _S_classic)->_M_add_reference();
else
- _M_impl = new _Impl(__res, 1);
- std::free(__res);
+ _M_impl = new _Impl(__res.c_str(), 1);
}
}
}