Commit f991b1d8 by Paolo Carlini Committed by Paolo Carlini

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
parent 968e3f93
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
......
...@@ -379,20 +379,24 @@ namespace std ...@@ -379,20 +379,24 @@ 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);
wchar_t* __wcs_ps = 0;
wchar_t* __wcs_ns = 0;
const char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc));
try
{
mbstate_t __state; mbstate_t __state;
size_t __len = strlen(__cpossign); size_t __len = strlen(__cpossign);
if (__len) if (__len)
{ {
++__len; ++__len;
memset(&__state, 0, sizeof(mbstate_t)); memset(&__state, 0, sizeof(mbstate_t));
wchar_t* __wcs = new wchar_t[__len]; __wcs_ps = new wchar_t[__len];
mbsrtowcs(__wcs, &__cpossign, __len, &__state); mbsrtowcs(__wcs_ps, &__cpossign, __len, &__state);
_M_data->_M_positive_sign = __wcs; _M_data->_M_positive_sign = __wcs_ps;
} }
else else
_M_data->_M_positive_sign = L""; _M_data->_M_positive_sign = L"";
char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc));
__len = strlen(__cnegsign); __len = strlen(__cnegsign);
if (!__nposn) if (!__nposn)
_M_data->_M_negative_sign = L"()"; _M_data->_M_negative_sign = L"()";
...@@ -400,9 +404,9 @@ namespace std ...@@ -400,9 +404,9 @@ namespace std
{ {
++__len; ++__len;
memset(&__state, 0, sizeof(mbstate_t)); memset(&__state, 0, sizeof(mbstate_t));
wchar_t* __wcs = new wchar_t[__len]; __wcs_ns = new wchar_t[__len];
mbsrtowcs(__wcs, &__cnegsign, __len, &__state); mbsrtowcs(__wcs_ns, &__cnegsign, __len, &__state);
_M_data->_M_negative_sign = __wcs; _M_data->_M_negative_sign = __wcs_ns;
} }
else else
_M_data->_M_negative_sign = L""; _M_data->_M_negative_sign = L"";
...@@ -419,6 +423,15 @@ namespace std ...@@ -419,6 +423,15 @@ namespace std
} }
else else
_M_data->_M_curr_symbol = L""; _M_data->_M_curr_symbol = L"";
}
catch (...)
{
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, _M_data->_M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS,
__cloc)); __cloc));
...@@ -489,6 +502,11 @@ namespace std ...@@ -489,6 +502,11 @@ 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);
wchar_t* __wcs_ps = 0;
wchar_t* __wcs_ns = 0;
const char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc));
try
{
mbstate_t __state; mbstate_t __state;
size_t __len; size_t __len;
__len = strlen(__cpossign); __len = strlen(__cpossign);
...@@ -496,14 +514,13 @@ namespace std ...@@ -496,14 +514,13 @@ namespace std
{ {
++__len; ++__len;
memset(&__state, 0, sizeof(mbstate_t)); memset(&__state, 0, sizeof(mbstate_t));
wchar_t* __wcs = new wchar_t[__len]; __wcs_ps = new wchar_t[__len];
mbsrtowcs(__wcs, &__cpossign, __len, &__state); mbsrtowcs(__wcs_ps, &__cpossign, __len, &__state);
_M_data->_M_positive_sign = __wcs; _M_data->_M_positive_sign = __wcs_ps;
} }
else else
_M_data->_M_positive_sign = L""; _M_data->_M_positive_sign = L"";
char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc));
__len = strlen(__cnegsign); __len = strlen(__cnegsign);
if (!__nposn) if (!__nposn)
_M_data->_M_negative_sign = L"()"; _M_data->_M_negative_sign = L"()";
...@@ -511,9 +528,9 @@ namespace std ...@@ -511,9 +528,9 @@ namespace std
{ {
++__len; ++__len;
memset(&__state, 0, sizeof(mbstate_t)); memset(&__state, 0, sizeof(mbstate_t));
wchar_t* __wcs = new wchar_t[__len]; __wcs_ns = new wchar_t[__len];
mbsrtowcs(__wcs, &__cnegsign, __len, &__state); mbsrtowcs(__wcs_ns, &__cnegsign, __len, &__state);
_M_data->_M_negative_sign = __wcs; _M_data->_M_negative_sign = __wcs_ns;
} }
else else
_M_data->_M_negative_sign = L""; _M_data->_M_negative_sign = L"";
...@@ -530,6 +547,15 @@ namespace std ...@@ -530,6 +547,15 @@ namespace std
} }
else else
_M_data->_M_curr_symbol = L""; _M_data->_M_curr_symbol = L"";
}
catch (...)
{
delete _M_data;
_M_data = 0;
delete __wcs_ps;
delete __wcs_ns;
__throw_exception_again;
}
_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));
......
...@@ -208,20 +208,20 @@ namespace std ...@@ -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 ...@@ -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 ...@@ -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);
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment