This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[Patch] Fix exception unsafety of __numpunt_cache
- From: Paolo Carlini <pcarlini at suse dot de>
- To: libstdc++ <libstdc++ at gcc dot gnu dot org>
- Cc: Benjamin Kosnik <bkoz at redhat dot com>
- Date: Mon, 24 Nov 2003 01:55:06 +0100
- Subject: [Patch] Fix exception unsafety of __numpunt_cache
Hi,
after all the work for locale.cc and localename.cc, it looks like
there are three remaining new calls not wrapped in try/catch, thus
leading to memory leaks if the second or third throw.
I have fixed the problem in the standard way, already used everywhere.
Tested x86-linux.
Ok with you, Benjamin?
Paolo.
//////////
2003-11-24 Paolo Carlini <pcarlini@suse.de>
* include/bits/locale_facets.h
(__numpunct_cache<>::_M_cache): Don't leak memory if
operator new throws; simplify a bit.
diff -prN libstdc++-v3-orig/include/bits/locale_facets.h libstdc++-v3/include/bits/locale_facets.h
*** libstdc++-v3-orig/include/bits/locale_facets.h Tue Nov 4 03:06:59 2003
--- libstdc++-v3/include/bits/locale_facets.h Mon Nov 24 01:49:39 2003
*************** namespace std
*** 648,678 ****
__numpunct_cache<_CharT>::_M_cache(const locale& __loc)
{
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
- string __grouping = __np.grouping();
- char* __group = new char[__grouping.length() + 1];
- __grouping.copy(__group, __grouping.length());
- __group[__grouping.length()] = char();
- _M_grouping = __group;
-
- _M_use_grouping = __grouping.length() != 0 && __grouping.data()[0] != 0;
! typedef basic_string<_CharT> __string_type;
! __string_type __true = __np.truename();
! _CharT* __truename = new _CharT[__true.length() + 1];
! __true.copy(__truename, __true.length());
! __truename[__true.length()] = _CharT();
! _M_truename = __truename;
!
! __string_type __false = __np.falsename();
! _CharT* __falsename = new _CharT[__false.length() + 1];
! __false.copy(__falsename, __false.length());
! __falsename[__false.length()] = _CharT();
! _M_falsename = __falsename;
!
_M_decimal_point = __np.decimal_point();
_M_thousands_sep = __np.thousands_sep();
!
const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
__ct.widen(__num_base::_S_atoms_out,
__num_base::_S_atoms_out + __num_base::_S_oend, _M_atoms_out);
--- 648,688 ----
__numpunct_cache<_CharT>::_M_cache(const locale& __loc)
{
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
! const string::size_type __len = __np.grouping().size();
! char* __grouping = NULL;
! __grouping = new char[__len + 1];
! __np.grouping().copy(__grouping, __len);
! __grouping[__len] = char();
! _M_grouping = __grouping;
! _M_use_grouping = __len && __np.grouping()[0] != 0;
! _CharT* __truename = NULL;
! try
! {
! typedef basic_string<_CharT> __string_type;
! typename __string_type::size_type __lentf = __np.truename().size();
! __truename = new _CharT[__lentf + 1];
! __np.truename().copy(__truename, __lentf);
! __truename[__lentf] = _CharT();
! _M_truename = __truename;
!
! __lentf = __np.falsename().size();
! _CharT* __falsename = new _CharT[__lentf + 1];
! __np.falsename().copy(__falsename, __lentf);
! __falsename[__lentf] = _CharT();
! _M_falsename = __falsename;
! }
! catch(...)
! {
! delete [] __grouping;
! delete [] __truename;
! __throw_exception_again;
! }
!
_M_decimal_point = __np.decimal_point();
_M_thousands_sep = __np.thousands_sep();
!
const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
__ct.widen(__num_base::_S_atoms_out,
__num_base::_S_atoms_out + __num_base::_S_oend, _M_atoms_out);
*************** namespace std
*** 680,686 ****
__ct.widen(__num_base::_S_atoms_in,
__num_base::_S_atoms_in + __num_base::_S_iend, _M_atoms_in);
_M_atoms_in[__num_base::_S_iend] = _CharT();
!
_M_allocated = true;
}
--- 690,696 ----
__ct.widen(__num_base::_S_atoms_in,
__num_base::_S_atoms_in + __num_base::_S_iend, _M_atoms_in);
_M_atoms_in[__num_base::_S_iend] = _CharT();
!
_M_allocated = true;
}