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
This commit is contained in:
Paolo Carlini 2003-10-16 17:24:07 +00:00 committed by Paolo Carlini
parent 968e3f935b
commit f991b1d853
3 changed files with 129 additions and 94 deletions

View File

@ -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> 2003-10-14 Jeff Bailey <jbailey@nisa.net>
PR libstdc++/12562 PR libstdc++/12562

View File

@ -379,47 +379,60 @@ namespace std
const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc); const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc);
const char* __ccurr = __nl_langinfo_l(__INT_CURR_SYMBOL, __cloc); const char* __ccurr = __nl_langinfo_l(__INT_CURR_SYMBOL, __cloc);
mbstate_t __state; wchar_t* __wcs_ps = 0;
size_t __len = strlen(__cpossign); wchar_t* __wcs_ns = 0;
if (__len) const char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc));
try
{ {
++__len; mbstate_t __state;
memset(&__state, 0, sizeof(mbstate_t)); size_t __len = strlen(__cpossign);
wchar_t* __wcs = new wchar_t[__len]; if (__len)
mbsrtowcs(__wcs, &__cpossign, __len, &__state); {
_M_data->_M_positive_sign = __wcs; ++__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 catch (...)
_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)
{ {
++__len; delete _M_data;
memset(&__state, 0, sizeof(mbstate_t)); _M_data = 0;
wchar_t* __wcs = new wchar_t[__len]; delete __wcs_ps;
mbsrtowcs(__wcs, &__ccurr, __len, &__state); delete __wcs_ns;
_M_data->_M_curr_symbol = __wcs; __throw_exception_again;
} }
else
_M_data->_M_curr_symbol = L"";
_M_data->_M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS, _M_data->_M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS,
__cloc)); __cloc));
char __pprecedes = *(__nl_langinfo_l(__INT_P_CS_PRECEDES, __cloc)); char __pprecedes = *(__nl_langinfo_l(__INT_P_CS_PRECEDES, __cloc));
@ -442,18 +455,18 @@ namespace std
} }
template<> template<>
void void
moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale __cloc, moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale __cloc,
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
const char*) const char*)
#else #else
const char* __name) const char* __name)
#endif #endif
{ {
if (!_M_data) if (!_M_data)
_M_data = new __moneypunct_cache<wchar_t>; _M_data = new __moneypunct_cache<wchar_t>;
if (!__cloc) if (!__cloc)
{ {
// "C" locale // "C" locale
_M_data->_M_decimal_point = L'.'; _M_data->_M_decimal_point = L'.';
@ -489,47 +502,60 @@ namespace std
const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc); const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc);
const char* __ccurr = __nl_langinfo_l(__CURRENCY_SYMBOL, __cloc); const char* __ccurr = __nl_langinfo_l(__CURRENCY_SYMBOL, __cloc);
mbstate_t __state; wchar_t* __wcs_ps = 0;
size_t __len; wchar_t* __wcs_ns = 0;
__len = strlen(__cpossign); const char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc));
if (__len) 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"";
}
catch (...)
{ {
++__len; delete _M_data;
memset(&__state, 0, sizeof(mbstate_t)); _M_data = 0;
wchar_t* __wcs = new wchar_t[__len]; delete __wcs_ps;
mbsrtowcs(__wcs, &__cpossign, __len, &__state); delete __wcs_ns;
_M_data->_M_positive_sign = __wcs; __throw_exception_again;
} }
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;
}
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"";
_M_data->_M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS, __cloc)); _M_data->_M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS, __cloc));
char __pprecedes = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc)); char __pprecedes = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc));

View File

@ -208,20 +208,20 @@ namespace std
} }
else else
{ {
char* __res; string __res;
// LANG may set a default different from "C". // LANG may set a default different from "C".
char* __env = std::getenv("LANG"); char* __env = std::getenv("LANG");
if (!__env || std::strcmp(__env, "") == 0 if (!__env || std::strcmp(__env, "") == 0
|| std::strcmp(__env, "C") == 0 || std::strcmp(__env, "C") == 0
|| std::strcmp(__env, "POSIX") == 0) || std::strcmp(__env, "POSIX") == 0)
__res = strdup("C"); __res = "C";
else else
__res = strdup(__env); __res = __env;
// Scan the categories looking for the first one // Scan the categories looking for the first one
// different from LANG. // different from LANG.
size_t __i = 0; size_t __i = 0;
if (std::strcmp(__res, "C") == 0) if (std::strcmp(__res.c_str(), "C") == 0)
for (; __i < _S_categories_size; ++__i) for (; __i < _S_categories_size; ++__i)
{ {
__env = std::getenv(_S_categories[__i]); __env = std::getenv(_S_categories[__i]);
@ -235,7 +235,7 @@ namespace std
{ {
__env = std::getenv(_S_categories[__i]); __env = std::getenv(_S_categories[__i]);
if (__env && std::strcmp(__env, "") != 0 if (__env && std::strcmp(__env, "") != 0
&& std::strcmp(__env, __res) != 0) && std::strcmp(__env, __res.c_str()) != 0)
break; break;
} }
@ -285,11 +285,10 @@ namespace std
} }
// ... otherwise either an additional instance of // ... otherwise either an additional instance of
// the "C" locale or LANG. // 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(); (_M_impl = _S_classic)->_M_add_reference();
else else
_M_impl = new _Impl(__res, 1); _M_impl = new _Impl(__res.c_str(), 1);
std::free(__res);
} }
} }
} }