This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [Patch] Fix libstdc++/12540


Hi again,

further testing (LC_ALL unset, LANG = xxx (!= "C"), at least one
category set to != xxx) revealed another possible memory leak path,
which may occur if memory allocation inside __str throws.

Therefore, instead of dealing explicitly, with this case too, seems
much better to me to change my original code for locale(const char*)
to not use strdup at all, but instead another basic_string for
__res too.

I have therefore tested the below, which I will commit soon.

Now, *always* for 12352 :)

==3673== LEAK SUMMARY:
==3673==    definitely lost: 0 bytes in 0 blocks.
==3673==    possibly lost:   0 bytes in 0 blocks.
==3673==    still reachable: 17840 bytes in 6 blocks.
==3673==    suppressed: 0 bytes in 0 blocks.

Paolo.

//////////
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.
diff -urN libstdc++-v3-orig/config/locale/gnu/monetary_members.cc libstdc++-v3/config/locale/gnu/monetary_members.cc
--- libstdc++-v3-orig/config/locale/gnu/monetary_members.cc	2003-07-18 04:27:15.000000000 +0200
+++ libstdc++-v3/config/locale/gnu/monetary_members.cc	2003-10-16 09:29:13.000000000 +0200
@@ -379,47 +379,60 @@
 	  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 @@
     }
 
   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 @@
 	  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;
+	  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_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)
+          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 -urN libstdc++-v3-orig/src/locale.cc libstdc++-v3/src/locale.cc
--- libstdc++-v3-orig/src/locale.cc	2003-10-14 12:37:36.000000000 +0200
+++ libstdc++-v3/src/locale.cc	2003-10-16 18:21:49.000000000 +0200
@@ -208,20 +208,20 @@
 	      }
 	    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 @@
 		    {
 		      __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 @@
 		  }
 		// ... 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);
 	      }
 	  }
       }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]