]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR libstdc++/12352 (Exception safety problems in src/localename.cc)
authorPaolo Carlini <pcarlini@suse.de>
Mon, 19 Jan 2004 00:12:55 +0000 (00:12 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Mon, 19 Jan 2004 00:12:55 +0000 (00:12 +0000)
2004-01-19  Paolo Carlini  <pcarlini@suse.de>

PR libstdc++/12352
PR libstdc++/12438
* include/bits/locale_classes.h (locale::locale(const locale&,
_Facet*)): Don't leak memory on exception.
* include/bits/locale_facets.tcc (locale::combine(const locale&)):
Likewise.
* src/locale.cc (locale::locale(const char*)): Likewise.
* src/localename.cc (locale::_Impl::~_Impl(),
locale::_Impl::_Impl(const _Impl&, size_t),
locale::_Impl::_Impl(const char*, size_t)): Likewise.
(locale::_Impl::_M_replace_categories(const _Impl*, category):
Tweak.

From-SVN: r76124

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/locale_classes.h
libstdc++-v3/include/bits/locale_facets.tcc
libstdc++-v3/src/locale.cc
libstdc++-v3/src/localename.cc

index 3d84488cb367eb52c916faa03034301f8f739323..5df60196bc6578d47062e7bffa6824587e7fc531 100644 (file)
@@ -1,3 +1,18 @@
+2004-01-19  Paolo Carlini  <pcarlini@suse.de>
+
+       PR libstdc++/12352
+       PR libstdc++/12438
+       * include/bits/locale_classes.h (locale::locale(const locale&,
+       _Facet*)): Don't leak memory on exception.
+       * include/bits/locale_facets.tcc (locale::combine(const locale&)):
+       Likewise.
+       * src/locale.cc (locale::locale(const char*)): Likewise.
+       * src/localename.cc (locale::_Impl::~_Impl(),
+       locale::_Impl::_Impl(const _Impl&, size_t),
+       locale::_Impl::_Impl(const char*, size_t)): Likewise.
+       (locale::_Impl::_M_replace_categories(const _Impl*, category):
+       Tweak.
+
 2004-01-12  Marc Espie <espie@openbsd.org>
 
        * src/Makefile.am (version.dep): backport from HEAD.
index ddd23fb9726a250026f1392d623d0bf7916a8bc0..0a44de63661d17d8be67f2bfbf6cd707c18906be 100644 (file)
@@ -302,14 +302,32 @@ namespace std
     locale::locale(const locale& __other, _Facet* __f)
     {
       _M_impl = new _Impl(*__other._M_impl, 1);
-      _M_impl->_M_install_facet(&_Facet::id, __f);
-      for (size_t __i = 0; 
-          __i < _S_categories_size + _S_extra_categories_size; ++__i)
+
+      char* _M_tmp_names[_S_categories_size + _S_extra_categories_size];
+      size_t __i = 0;
+      try
+       {
+         for (; __i < _S_categories_size
+                      + _S_extra_categories_size; ++__i)
+           {
+             _M_tmp_names[__i] = new char[2];
+             strcpy(_M_tmp_names[__i], "*");
+           }
+         _M_impl->_M_install_facet(&_Facet::id, __f);
+       }
+      catch(...)
+       {
+         _M_impl->_M_remove_reference();
+         for (size_t __j = 0; __j < __i; ++__j)
+           delete [] _M_tmp_names[__j];          
+         __throw_exception_again;
+       }
+
+      for (size_t __k = 0; __k < _S_categories_size
+                                + _S_extra_categories_size; ++__k)
        {
-         delete [] _M_impl->_M_names[__i];
-         char* __new = new char[2];
-         strcpy(__new, "*");
-         _M_impl->_M_names[__i] = __new;
+         delete [] _M_impl->_M_names[__k];
+         _M_impl->_M_names[__k] = _M_tmp_names[__k];
        }
     }
 
index 2563a9595d1d487c23679b7f82b9aac35aa27545..f2a1ce04d23c05836f7f758d775d8db1f97ef834 100644 (file)
@@ -51,7 +51,15 @@ namespace std
     locale::combine(const locale& __other) const
     {
       _Impl* __tmp = new _Impl(*_M_impl, 1);
-      __tmp->_M_replace_facet(__other._M_impl, &_Facet::id);
+      try
+       {
+         __tmp->_M_replace_facet(__other._M_impl, &_Facet::id);
+       }
+      catch(...)
+       {
+         __tmp->_M_remove_reference();
+         __throw_exception_again;
+       }
       return locale(__tmp);
     }
 
index 17ccdc2e4c688224844d9de7b5f582be3be45d32..745327591816d181259c950810c83d8a5ff38304 100644 (file)
@@ -194,19 +194,19 @@ namespace std
              }
            else
              {
-               char* __res;
+               string __res;
                // LANG may set a default different from "C".
                char* __env = getenv("LANG");
                if (!__env || strcmp(__env, "") == 0 || strcmp(__env, "C") == 0
                    || 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 (strcmp(__res, "C") == 0)
+               if (__res == "C")
                  for (; __i < _S_categories_size
                         + _S_extra_categories_size; ++__i)
                    {
@@ -222,7 +222,7 @@ namespace std
                    {
                      __env = getenv(_S_categories[__i]);
                      if (__env && strcmp(__env, "") != 0 
-                         && strcmp(__env, __res) != 0
+                         && __res != __env
                        break;
                    }
        
@@ -273,11 +273,10 @@ namespace std
                  }
                // ... otherwise either an additional instance of
                // the "C" locale or LANG.
-               else if (strcmp(__res, "C") == 0)
+               else if (__res == "C")
                  (_M_impl = _S_classic)->_M_add_reference();
                else
-                 _M_impl = new _Impl(__res, 1);
-               free(__res);
+                 _M_impl = new _Impl(__res.c_str(), 1);
              }
          }
       }
index ec35fdb1eaa0c55088437ecad8ce2eaf922c1dfd..38311fb64f7bc060bddd42f0966b56ca5d914ccc 100644 (file)
@@ -84,17 +84,21 @@ namespace std
   ~_Impl() throw()
   {
     // Clean up facets, then caches.  No cache refcounts for now.
-    for (size_t __i = 0; __i < _M_facets_size; ++__i)
-      if (_M_facets[__i])
-       _M_facets[__i]->_M_remove_reference();
-    for (size_t __i = _M_facets_size; __i < 2*_M_facets_size; ++__i)
-      if (_M_facets[__i])
-       delete (__locale_cache_base*)_M_facets[__i];
+    if (_M_facets)
+      {
+       for (size_t __i = 0; __i < _M_facets_size; ++__i)
+         if (_M_facets[__i])
+           _M_facets[__i]->_M_remove_reference();
+
+       for (size_t __i = _M_facets_size; __i < 2*_M_facets_size; ++__i)
+         if (_M_facets[__i])
+           delete (__locale_cache_base*)_M_facets[__i];
+      }
     delete [] _M_facets;
 
     for (size_t __i = 0; 
         __i < _S_categories_size + _S_extra_categories_size; ++__i)
-      delete [] _M_names[__i];  
+      delete [] _M_names[__i];
   }
 
   // Clone existing _Impl object.
@@ -102,30 +106,34 @@ namespace std
   _Impl(const _Impl& __imp, size_t __refs)
   : _M_references(__refs), _M_facets_size(__imp._M_facets_size) // XXX
   {
+    _M_facets = 0;
+    for (size_t __i = 0; __i < _S_categories_size
+                        + _S_extra_categories_size; ++__i)
+      _M_names[__i] = 0;
     try
       { 
        // Space for facets and matching caches
        _M_facets = new facet*[2*_M_facets_size]; 
        for (size_t __i = 0; __i < 2*_M_facets_size; ++__i)
          _M_facets[__i] = 0;
+       for (size_t __i = 0; __i < _M_facets_size; ++__i)
+         {
+           _M_facets[__i] = __imp._M_facets[__i];
+           if (_M_facets[__i])
+             _M_facets[__i]->_M_add_reference();
+         }
+       for (size_t __i = 0; 
+            __i < _S_categories_size + _S_extra_categories_size; ++__i)
+         {
+           char* __new = new char[strlen(__imp._M_names[__i]) + 1];
+           strcpy(__new, __imp._M_names[__i]);
+           _M_names[__i] = __new;
+         }
       }
-    catch(...) 
-      {
-       delete [] _M_facets;
-       __throw_exception_again;
-      }
-    for (size_t __i = 0; __i < _M_facets_size; ++__i)
-      {
-       _M_facets[__i] = __imp._M_facets[__i];
-       if (_M_facets[__i])
-         _M_facets[__i]->_M_add_reference();
-      }
-    for (size_t __i = 0; 
-        __i < _S_categories_size + _S_extra_categories_size; ++__i)
+    catch(...)
       {
-       char* __new = new char[strlen(__imp._M_names[__i]) + 1];
-       strcpy(__new, __imp._M_names[__i]);
-       _M_names[__i] = __new;
+       this->~_Impl();
+       __throw_exception_again;        
       }
   }
 
@@ -139,80 +147,85 @@ namespace std
     __c_locale __cloc;
     locale::facet::_S_create_c_locale(__cloc, __s);
 
+    _M_facets = 0;
+    for (size_t __i = 0; __i < _S_categories_size
+                        + _S_extra_categories_size; ++__i)
+      _M_names[__i] = 0;       
     try
       {
        // Space for facets and matching caches
        _M_facets = new facet*[2*_M_facets_size]; 
        for (size_t __i = 0; __i < 2*_M_facets_size; ++__i)
          _M_facets[__i] = 0;
-      }
-    catch(...) 
-      {
-       delete [] _M_facets;
-       __throw_exception_again;
-      }
 
-    // Name all the categories.
-    size_t __len = strlen(__s);
-    if (!strchr(__s, ';'))
-      {
-       for (size_t __i = 0; 
-            __i < _S_categories_size + _S_extra_categories_size; ++__i)
+       // Name all the categories.
+       size_t __len = strlen(__s);
+       if (!strchr(__s, ';'))
          {
-           _M_names[__i] = new char[__len + 1];
-           strcpy(_M_names[__i], __s);
+           for (size_t __i = 0; 
+                __i < _S_categories_size + _S_extra_categories_size; ++__i)
+             {
+               _M_names[__i] = new char[__len + 1];
+               strcpy(_M_names[__i], __s);
+             }
          }
-      }
-    else
-      {
-       const char* __beg = __s;
-       for (size_t __i = 0; 
-            __i < _S_categories_size + _S_extra_categories_size; ++__i)
+       else
          {
-           __beg = strchr(__beg, '=') + 1;
-           const char* __end = strchr(__beg, ';');
-           if (!__end)
-             __end = __s + __len;
-           char* __new = new char[__end - __beg + 1];
-           memcpy(__new, __beg, __end - __beg);
-           __new[__end - __beg] = '\0';
-           _M_names[__i] = __new;
+           const char* __beg = __s;
+           for (size_t __i = 0; 
+                __i < _S_categories_size + _S_extra_categories_size; ++__i)
+             {
+               __beg = strchr(__beg, '=') + 1;
+               const char* __end = strchr(__beg, ';');
+               if (!__end)
+                 __end = __s + __len;
+               char* __new = new char[__end - __beg + 1];
+               memcpy(__new, __beg, __end - __beg);
+               __new[__end - __beg] = '\0';
+               _M_names[__i] = __new;
+             }
          }
-      }
 
-    // Construct all standard facets and add them to _M_facets.  
-    _M_init_facet(new std::ctype<char>(__cloc, 0, false));
-    _M_init_facet(new codecvt<char, char, mbstate_t>);
-    _M_init_facet(new numpunct<char>(__cloc));
-    _M_init_facet(new num_get<char>);
-    _M_init_facet(new num_put<char>);
-    _M_init_facet(new std::collate<char>(__cloc));
-    _M_init_facet(new moneypunct<char, false>(__cloc, __s));
-    _M_init_facet(new moneypunct<char, true>(__cloc, __s));
-    _M_init_facet(new money_get<char>);
-    _M_init_facet(new money_put<char>);
-    _M_init_facet(new __timepunct<char>(__cloc, __s));
-    _M_init_facet(new time_get<char>);
-    _M_init_facet(new time_put<char>);
-    _M_init_facet(new std::messages<char>(__cloc, __s));
+       // Construct all standard facets and add them to _M_facets.  
+       _M_init_facet(new std::ctype<char>(__cloc, 0, false));
+       _M_init_facet(new codecvt<char, char, mbstate_t>);
+       _M_init_facet(new numpunct<char>(__cloc));
+       _M_init_facet(new num_get<char>);
+       _M_init_facet(new num_put<char>);
+       _M_init_facet(new std::collate<char>(__cloc));
+       _M_init_facet(new moneypunct<char, false>(__cloc, __s));
+       _M_init_facet(new moneypunct<char, true>(__cloc, __s));
+       _M_init_facet(new money_get<char>);
+       _M_init_facet(new money_put<char>);
+       _M_init_facet(new __timepunct<char>(__cloc, __s));
+       _M_init_facet(new time_get<char>);
+       _M_init_facet(new time_put<char>);
+       _M_init_facet(new std::messages<char>(__cloc, __s));
        
 #ifdef  _GLIBCPP_USE_WCHAR_T
-    _M_init_facet(new std::ctype<wchar_t>(__cloc));
-    _M_init_facet(new codecvt<wchar_t, char, mbstate_t>);
-    _M_init_facet(new numpunct<wchar_t>(__cloc));
-    _M_init_facet(new num_get<wchar_t>);
-    _M_init_facet(new num_put<wchar_t>);
-    _M_init_facet(new std::collate<wchar_t>(__cloc));
-    _M_init_facet(new moneypunct<wchar_t, false>(__cloc, __s));
-    _M_init_facet(new moneypunct<wchar_t, true>(__cloc, __s));
-    _M_init_facet(new money_get<wchar_t>);
-    _M_init_facet(new money_put<wchar_t>);
-    _M_init_facet(new __timepunct<wchar_t>(__cloc, __s));
-    _M_init_facet(new time_get<wchar_t>);
-    _M_init_facet(new time_put<wchar_t>);
-    _M_init_facet(new std::messages<wchar_t>(__cloc, __s));
+       _M_init_facet(new std::ctype<wchar_t>(__cloc));
+       _M_init_facet(new codecvt<wchar_t, char, mbstate_t>);
+       _M_init_facet(new numpunct<wchar_t>(__cloc));
+       _M_init_facet(new num_get<wchar_t>);
+       _M_init_facet(new num_put<wchar_t>);
+       _M_init_facet(new std::collate<wchar_t>(__cloc));
+       _M_init_facet(new moneypunct<wchar_t, false>(__cloc, __s));
+       _M_init_facet(new moneypunct<wchar_t, true>(__cloc, __s));
+       _M_init_facet(new money_get<wchar_t>);
+       _M_init_facet(new money_put<wchar_t>);
+       _M_init_facet(new __timepunct<wchar_t>(__cloc, __s));
+       _M_init_facet(new time_get<wchar_t>);
+       _M_init_facet(new time_put<wchar_t>);
+       _M_init_facet(new std::messages<wchar_t>(__cloc, __s));
 #endif   
-    locale::facet::_S_destroy_c_locale(__cloc);
+       locale::facet::_S_destroy_c_locale(__cloc);
+      }
+    catch(...)
+      {
+       locale::facet::_S_destroy_c_locale(__cloc);
+       this->~_Impl();
+       __throw_exception_again;
+      }    
   }
 
   // Construct "C" _Impl.
@@ -313,9 +326,9 @@ namespace std
            if (strcmp(_M_names[__ix], "*") != 0 
                && strcmp(__imp->_M_names[__ix], "*") != 0)
              {
-               delete [] _M_names[__ix];
                char* __new = new char[strlen(__imp->_M_names[__ix]) + 1];
                strcpy(__new, __imp->_M_names[__ix]);
+               delete [] _M_names[__ix];
                _M_names[__ix] = __new;
              }
          }