re PR libstdc++/23953 (using stringstreams causes crashes with some locales)

2005-09-30  Paolo Carlini  <pcarlini@suse.de>

	PR libstdc++/23953
	* include/bits/locale_facets.tcc (__numpunct_cache<>::_M_cache,
	__moneypunct_cache<>::_M_cache): Check that grouping()[0] > 0.
	(__verify_grouping): Do the last check only if __grouping[__min] > 0.
	(__add_grouping<>): End recursion if *__gbeg <= 0.
	* testsuite/22_locale/num_get/get/char/23953.cc: New.
	* testsuite/22_locale/num_get/get/wchar_t/23953.cc: Likewise.
	* testsuite/22_locale/num_put/put/char/23953.cc: Likewise.
	* testsuite/22_locale/num_put/put/wchar_t/23953.cc: Likewise.

From-SVN: r104814
This commit is contained in:
Paolo Carlini 2005-09-30 08:39:52 +00:00 committed by Paolo Carlini
parent 7a6a7d975b
commit eae6e95b7f
6 changed files with 341 additions and 6 deletions

View File

@ -1,3 +1,15 @@
2005-09-30 Paolo Carlini <pcarlini@suse.de>
PR libstdc++/23953
* include/bits/locale_facets.tcc (__numpunct_cache<>::_M_cache,
__moneypunct_cache<>::_M_cache): Check that grouping()[0] > 0.
(__verify_grouping): Do the last check only if __grouping[__min] > 0.
(__add_grouping<>): End recursion if *__gbeg <= 0.
* testsuite/22_locale/num_get/get/char/23953.cc: New.
* testsuite/22_locale/num_get/get/wchar_t/23953.cc: Likewise.
* testsuite/22_locale/num_put/put/char/23953.cc: Likewise.
* testsuite/22_locale/num_put/put/wchar_t/23953.cc: Likewise.
2005-09-29 Chris Jefferson <chris@bubblescope.net>
PR libstdc++/23978

View File

@ -193,7 +193,8 @@ namespace std
char* __grouping = new char[_M_grouping_size];
__np.grouping().copy(__grouping, _M_grouping_size);
_M_grouping = __grouping;
_M_use_grouping = _M_grouping_size && __np.grouping()[0] != 0;
_M_use_grouping = (_M_grouping_size
&& static_cast<signed char>(__np.grouping()[0]) > 0);
_M_truename_size = __np.truename().size();
_CharT* __truename = new _CharT[_M_truename_size];
@ -228,7 +229,8 @@ namespace std
char* __grouping = new char[_M_grouping_size];
__mp.grouping().copy(__grouping, _M_grouping_size);
_M_grouping = __grouping;
_M_use_grouping = _M_grouping_size && __mp.grouping()[0] != 0;
_M_use_grouping = (_M_grouping_size
&& static_cast<signed char>(__mp.grouping()[0]) > 0);
_M_decimal_point = __mp.decimal_point();
_M_thousands_sep = __mp.thousands_sep();
@ -2471,9 +2473,11 @@ namespace std
__test = __grouping_tmp[__i] == __grouping[__j];
for (; __i && __test; --__i)
__test = __grouping_tmp[__i] == __grouping[__min];
// ... but the last parsed grouping can be <= numpunct
// grouping.
__test &= __grouping_tmp[0] <= __grouping[__min];
// ... but the first parsed grouping can be <= numpunct
// grouping (only do the check if the numpunct char is > 0
// because <= 0 means any size is ok).
if (static_cast<signed char>(__grouping[__min]) > 0)
__test &= __grouping_tmp[0] <= __grouping[__min];
return __test;
}
@ -2483,7 +2487,8 @@ namespace std
const char* __gbeg, size_t __gsize,
const _CharT* __first, const _CharT* __last)
{
if (__last - __first > *__gbeg)
if (__last - __first > *__gbeg
&& static_cast<signed char>(*__gbeg) > 0)
{
const bool __bump = __gsize != 1;
__s = std::__add_grouping(__s, __sep, __gbeg + __bump,

View File

@ -0,0 +1,83 @@
// 2005-09-30 Paolo Carlini <pcarlini@suse.de>
// Copyright (C) 2005 Free Software Foundation
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 22.2.2.1.1 num_get members
#include <locale>
#include <sstream>
#include <testsuite_hooks.h>
using namespace std;
struct Punct1: numpunct<char>
{ string do_grouping() const { return string(1, char(-1)); } };
struct Punct2: numpunct<char>
{ string do_grouping() const { return string("\002") + char(-1); } };
struct Punct3: numpunct<char>
{ string do_grouping() const { return string("\001\002") + char(-1); } };
// libstdc++/23953
void test01()
{
bool test __attribute__((unused)) = true;
typedef istreambuf_iterator<char> iterator_type;
istringstream iss1, iss2, iss3;
iss1.imbue(locale(iss1.getloc(), new Punct1));
iss2.imbue(locale(iss2.getloc(), new Punct2));
iss3.imbue(locale(iss3.getloc(), new Punct3));
const num_get<char>& ng1 = use_facet<num_get<char> >(iss1.getloc());
const num_get<char>& ng2 = use_facet<num_get<char> >(iss2.getloc());
const num_get<char>& ng3 = use_facet<num_get<char> >(iss3.getloc());
ios_base::iostate err = ios_base::goodbit;
iterator_type end;
long l = 0l;
long l1 = 12345l;
long l2 = 12345678l;
double d = 0.0;
double d1 = 1234567.0;
iss1.str("12345");
err = ios_base::goodbit;
end = ng1.get(iss1.rdbuf(), 0, iss1, err, l);
VERIFY( err == ios_base::eofbit );
VERIFY( l == l1 );
iss2.str("123456,78");
err = ios_base::goodbit;
end = ng2.get(iss2.rdbuf(), 0, iss2, err, l);
VERIFY( err == ios_base::eofbit );
VERIFY( l == l2 );
iss3.str("1234,56,7.0");
err = ios_base::goodbit;
end = ng3.get(iss3.rdbuf(), 0, iss3, err, d);
VERIFY( err == ios_base::eofbit );
VERIFY( d == d1 );
}
int main()
{
test01();
return 0;
}

View File

@ -0,0 +1,83 @@
// 2005-09-30 Paolo Carlini <pcarlini@suse.de>
// Copyright (C) 2005 Free Software Foundation
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 22.2.2.1.1 num_get members
#include <locale>
#include <sstream>
#include <testsuite_hooks.h>
using namespace std;
struct Punct1: numpunct<wchar_t>
{ string do_grouping() const { return string(1, char(-1)); } };
struct Punct2: numpunct<wchar_t>
{ string do_grouping() const { return string("\002") + char(-1); } };
struct Punct3: numpunct<wchar_t>
{ string do_grouping() const { return string("\001\002") + char(-1); } };
// libstdc++/23953
void test01()
{
bool test __attribute__((unused)) = true;
typedef istreambuf_iterator<wchar_t> iterator_type;
wistringstream iss1, iss2, iss3;
iss1.imbue(locale(iss1.getloc(), new Punct1));
iss2.imbue(locale(iss2.getloc(), new Punct2));
iss3.imbue(locale(iss3.getloc(), new Punct3));
const num_get<wchar_t>& ng1 = use_facet<num_get<wchar_t> >(iss1.getloc());
const num_get<wchar_t>& ng2 = use_facet<num_get<wchar_t> >(iss2.getloc());
const num_get<wchar_t>& ng3 = use_facet<num_get<wchar_t> >(iss3.getloc());
ios_base::iostate err = ios_base::goodbit;
iterator_type end;
long l = 0l;
long l1 = 12345l;
long l2 = 12345678l;
double d = 0.0;
double d1 = 1234567.0;
iss1.str(L"12345");
err = ios_base::goodbit;
end = ng1.get(iss1.rdbuf(), 0, iss1, err, l);
VERIFY( err == ios_base::eofbit );
VERIFY( l == l1 );
iss2.str(L"123456,78");
err = ios_base::goodbit;
end = ng2.get(iss2.rdbuf(), 0, iss2, err, l);
VERIFY( err == ios_base::eofbit );
VERIFY( l == l2 );
iss3.str(L"1234,56,7.0");
err = ios_base::goodbit;
end = ng3.get(iss3.rdbuf(), 0, iss3, err, d);
VERIFY( err == ios_base::eofbit );
VERIFY( d == d1 );
}
int main()
{
test01();
return 0;
}

View File

@ -0,0 +1,76 @@
// 2005-09-30 Paolo Carlini <pcarlini@suse.de>
// Copyright (C) 2005 Free Software Foundation
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 22.2.2.2.1 num_put members
#include <locale>
#include <sstream>
#include <testsuite_hooks.h>
using namespace std;
struct Punct1: numpunct<char>
{ string do_grouping() const { return string(1, char(-1)); } };
struct Punct2: numpunct<char>
{ string do_grouping() const { return string("\002") + char(-1); } };
struct Punct3: numpunct<char>
{ string do_grouping() const { return string("\001\002") + char(-1); } };
// libstdc++/23953
void test01()
{
bool test __attribute__((unused)) = true;
ostringstream oss1, oss2, oss3;
string result1, result2, result3;
oss1.imbue(locale(oss1.getloc(), new Punct1));
oss2.imbue(locale(oss2.getloc(), new Punct2));
oss3.imbue(locale(oss3.getloc(), new Punct3));
const num_put<char>& ng1 = use_facet<num_put<char> >(oss1.getloc());
const num_put<char>& ng2 = use_facet<num_put<char> >(oss2.getloc());
const num_put<char>& ng3 = use_facet<num_put<char> >(oss3.getloc());
long l1 = 12345l;
long l2 = 12345678l;
double d1 = 1234567.0;
ng1.put(oss1.rdbuf(), oss1, '+', l1);
result1 = oss1.str();
VERIFY( result1 == "12345" );
ng2.put(oss2.rdbuf(), oss2, '+', l2);
result2 = oss2.str();
VERIFY( result2 == "123456,78" );
oss3.precision(1);
oss3.setf(ios_base::fixed, ios_base::floatfield);
ng3.put(oss3.rdbuf(), oss3, '+', d1);
result3 = oss3.str();
VERIFY( result3 == "1234,56,7.0" );
}
int main()
{
test01();
return 0;
}

View File

@ -0,0 +1,76 @@
// 2005-09-30 Paolo Carlini <pcarlini@suse.de>
// Copyright (C) 2005 Free Software Foundation
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 22.2.2.2.1 num_put members
#include <locale>
#include <sstream>
#include <testsuite_hooks.h>
using namespace std;
struct Punct1: numpunct<wchar_t>
{ string do_grouping() const { return string(1, char(-1)); } };
struct Punct2: numpunct<wchar_t>
{ string do_grouping() const { return string("\002") + char(-1); } };
struct Punct3: numpunct<wchar_t>
{ string do_grouping() const { return string("\001\002") + char(-1); } };
// libstdc++/23953
void test01()
{
bool test __attribute__((unused)) = true;
wostringstream oss1, oss2, oss3;
wstring result1, result2, result3;
oss1.imbue(locale(oss1.getloc(), new Punct1));
oss2.imbue(locale(oss2.getloc(), new Punct2));
oss3.imbue(locale(oss3.getloc(), new Punct3));
const num_put<wchar_t>& ng1 = use_facet<num_put<wchar_t> >(oss1.getloc());
const num_put<wchar_t>& ng2 = use_facet<num_put<wchar_t> >(oss2.getloc());
const num_put<wchar_t>& ng3 = use_facet<num_put<wchar_t> >(oss3.getloc());
long l1 = 12345l;
long l2 = 12345678l;
double d1 = 1234567.0;
ng1.put(oss1.rdbuf(), oss1, L'+', l1);
result1 = oss1.str();
VERIFY( result1 == L"12345" );
ng2.put(oss2.rdbuf(), oss2, L'+', l2);
result2 = oss2.str();
VERIFY( result2 == L"123456,78" );
oss3.precision(1);
oss3.setf(ios_base::fixed, ios_base::floatfield);
ng3.put(oss3.rdbuf(), oss3, L'+', d1);
result3 = oss3.str();
VERIFY( result3 == L"1234,56,7.0" );
}
int main()
{
test01();
return 0;
}