re PR libstdc++/9817 (collate::compare doesn't handle nul characters.)

2003-03-07  Petur Runolfsson  <peturr02@ru.is>

	PR libstdc++/9817
	* include/bits/locale_facets.tcc
	(collate::do_compare, collate::do_transform):
	Handle nul characters in input.
	* testsuite/22_locale/collate/compare/char/3.cc:  New test.
	* testsuite/22_locale/collate/compare/wchar_t/3.cc:  New test.
	* testsuite/22_locale/collate/transform/char/3.cc:  New test.
	* testsuite/22_locale/collate/transform/wchar_t/3.cc:  New test.

From-SVN: r63946
This commit is contained in:
Petur Runolfsson 2003-03-07 17:24:47 +00:00 committed by Benjamin Kosnik
parent dfa7f440a0
commit 5040d6912c
6 changed files with 440 additions and 11 deletions

View File

@ -1,3 +1,14 @@
2003-03-07 Petur Runolfsson <peturr02@ru.is>
PR libstdc++/9817
* include/bits/locale_facets.tcc
(collate::do_compare, collate::do_transform):
Handle nul characters in input.
* testsuite/22_locale/collate/compare/char/3.cc: New test.
* testsuite/22_locale/collate/compare/wchar_t/3.cc: New test.
* testsuite/22_locale/collate/transform/char/3.cc: New test.
* testsuite/22_locale/collate/transform/wchar_t/3.cc: New test.
2003-03-07 Jerry Quinn <jlquinn@optonline.net>
* include/bits/streambuf_iterator.h (_M_put): Set _M_failed if

View File

@ -2038,9 +2038,37 @@ namespace std
do_compare(const _CharT* __lo1, const _CharT* __hi1,
const _CharT* __lo2, const _CharT* __hi2) const
{
// strcoll assumes zero-terminated strings so we make a copy
// and then put a zero at the end.
const string_type __one(__lo1, __hi1);
const string_type __two(__lo2, __hi2);
return _M_compare(__one.c_str(), __two.c_str());
const _CharT* __p = __one.c_str();
const _CharT* __pend = __one.c_str() + __one.length();
const _CharT* __q = __two.c_str();
const _CharT* __qend = __two.c_str() + __two.length();
// strcoll stops when it sees a nul character so we break
// the strings into zero-terminated substrings and pass those
// to strcoll.
for (;;)
{
int __res = _M_compare(__p, __q);
if (__res)
return __res;
__p += char_traits<_CharT>::length(__p);
__q += char_traits<_CharT>::length(__q);
if (__p == __pend && __q == __qend)
return 0;
else if (__p == __pend)
return -1;
else if (__q == __qend)
return 1;
__p++;
__q++;
}
}
template<typename _CharT>
@ -2048,19 +2076,43 @@ namespace std
collate<_CharT>::
do_transform(const _CharT* __lo, const _CharT* __hi) const
{
// strxfrm assumes zero-terminated strings so we make a copy
string_type __str(__lo, __hi);
const _CharT* __p = __str.c_str();
const _CharT* __pend = __str.c_str() + __str.length();
size_t __len = (__hi - __lo) * 2;
// First try a buffer perhaps big enough.
_CharT* __c =
static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len));
size_t __res = _M_transform(__c, __lo, __len);
// If the buffer was not large enough, try again with the correct size.
if (__res >= __len)
string_type __ret;
// strxfrm stops when it sees a nul character so we break
// the string into zero-terminated substrings and pass those
// to strxfrm.
for (;;)
{
__c = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
* (__res + 1)));
_M_transform(__c, __lo, __res + 1);
// First try a buffer perhaps big enough.
_CharT* __c =
static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len));
size_t __res = _M_transform(__c, __p, __len);
// If the buffer was not large enough, try again with the
// correct size.
if (__res >= __len)
{
__len = __res + 1;
__c = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
* __len));
__res = _M_transform(__c, __p, __res + 1);
}
__ret.append(__c, __res);
__p += char_traits<_CharT>::length(__p);
if (__p == __pend)
return __ret;
__p++;
__ret.push_back(_CharT());
}
return string_type(__c);
}
template<typename _CharT>

View File

@ -0,0 +1,90 @@
// 2003-02-24 Petur Runolfsson <peturr02@ru.is>
// Copyright (C) 2003 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 22.2.4.1.1 collate members
#include <locale>
#include <testsuite_hooks.h>
// Test handling of strings containing nul characters
void test03()
{
using namespace std;
typedef std::collate<char>::string_type string_type;
bool test = true;
// basic construction
locale loc_c = locale::classic();
locale loc_de("de_DE");
VERIFY( loc_c != loc_de );
// cache the collate facets
const collate<char>& coll_c = use_facet<collate<char> >(loc_c);
const collate<char>& coll_de = use_facet<collate<char> >(loc_de);
// int compare(const charT*, const charT*, const charT*, const charT*) const
const char* strlit1 = "a\0a\0";
const char* strlit2 = "a\0b\0";
const char* strlit3 = "a\0\xc4\0";
const char* strlit4 = "a\0B\0";
const char* strlit5 = "aa\0";
const char* strlit6 = "b\0a\0";
int i;
i = coll_c.compare(strlit1, strlit1 + 3, strlit2, strlit2 + 3);
VERIFY( i == -1 );
i = coll_de.compare(strlit1, strlit1 + 3, strlit2, strlit2 + 3);
VERIFY( i == -1 );
i = coll_c.compare(strlit3, strlit3 + 3, strlit4, strlit4 + 3);
VERIFY( i == 1 );
i = coll_de.compare(strlit3, strlit3 + 3, strlit4, strlit4 + 3);
VERIFY( i == -1 );
i = coll_c.compare(strlit1, strlit1 + 3, strlit1, strlit1 + 4);
VERIFY( i == -1 );
i = coll_de.compare(strlit3, strlit3 + 4, strlit3, strlit3 + 3);
VERIFY( i == 1 );
i = coll_c.compare(strlit1, strlit1 + 4, strlit4, strlit4 + 1);
VERIFY( i == 1 );
i = coll_de.compare(strlit3, strlit3 + 3, strlit3, strlit3 + 3);
VERIFY( i == 0 );
i = coll_c.compare(strlit1, strlit1 + 2, strlit1, strlit1 + 4);
VERIFY( i == -1 );
i = coll_de.compare(strlit1, strlit1 + 3, strlit5, strlit5 + 3);
VERIFY( i == -1 );
i = coll_c.compare(strlit6, strlit6 + 3, strlit1, strlit1 + 3);
VERIFY( i == 1 );
}
int main()
{
test03();
return 0;
}

View File

@ -0,0 +1,90 @@
// 2003-02-24 Petur Runolfsson <peturr02@ru.is>
// Copyright (C) 2003 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 22.2.4.1.1 collate members
#include <locale>
#include <testsuite_hooks.h>
// Test handling of strings containing nul characters
void test03()
{
using namespace std;
typedef std::collate<wchar_t>::string_type string_type;
bool test = true;
// basic construction
locale loc_c = locale::classic();
locale loc_de("de_DE");
VERIFY( loc_c != loc_de );
// cache the collate facets
const collate<wchar_t>& coll_c = use_facet<collate<wchar_t> >(loc_c);
const collate<wchar_t>& coll_de = use_facet<collate<wchar_t> >(loc_de);
// int compare(const charT*, const charT*, const charT*, const charT*) const
const wchar_t* strlit1 = L"a\0a\0";
const wchar_t* strlit2 = L"a\0b\0";
const wchar_t* strlit3 = L"a\0\xc4\0";
const wchar_t* strlit4 = L"a\0B\0";
const wchar_t* strlit5 = L"aa\0";
const wchar_t* strlit6 = L"b\0a\0";
int i;
i = coll_c.compare(strlit1, strlit1 + 3, strlit2, strlit2 + 3);
VERIFY( i == -1 );
i = coll_de.compare(strlit1, strlit1 + 3, strlit2, strlit2 + 3);
VERIFY( i == -1 );
i = coll_c.compare(strlit3, strlit3 + 3, strlit4, strlit4 + 3);
VERIFY( i == 1 );
i = coll_de.compare(strlit3, strlit3 + 3, strlit4, strlit4 + 3);
VERIFY( i == -1 );
i = coll_c.compare(strlit1, strlit1 + 3, strlit1, strlit1 + 4);
VERIFY( i == -1 );
i = coll_de.compare(strlit3, strlit3 + 4, strlit3, strlit3 + 3);
VERIFY( i == 1 );
i = coll_c.compare(strlit1, strlit1 + 4, strlit4, strlit4 + 1);
VERIFY( i == 1 );
i = coll_de.compare(strlit3, strlit3 + 3, strlit3, strlit3 + 3);
VERIFY( i == 0 );
i = coll_c.compare(strlit1, strlit1 + 2, strlit1, strlit1 + 4);
VERIFY( i == -1 );
i = coll_de.compare(strlit1, strlit1 + 3, strlit5, strlit5 + 3);
VERIFY( i == -1 );
i = coll_c.compare(strlit6, strlit6 + 3, strlit1, strlit1 + 3);
VERIFY( i == 1 );
}
int main()
{
test03();
return 0;
}

View File

@ -0,0 +1,93 @@
// 2003-02-24 Petur Runolfsson <peturr02@ru.is>
// Copyright (C) 2003 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 22.2.4.1.1 collate members
#include <locale>
#include <testsuite_hooks.h>
void test03()
{
using namespace std;
typedef std::collate<char>::string_type string_type;
bool test = true;
// basic construction
locale loc_c = locale::classic();
locale loc_de("de_DE");
VERIFY( loc_c != loc_de );
// cache the collate facets
const collate<char>& coll_c = use_facet<collate<char> >(loc_c);
const collate<char>& coll_de = use_facet<collate<char> >(loc_de);
const char* strlit1 = "a\0a\0";
const char* strlit2 = "a\0b\0";
const char* strlit3 = "a\0\xc4\0";
const char* strlit4 = "a\0B\0";
const char* strlit5 = "aa\0";
const char* strlit6 = "b\0a\0";
int i;
string_type str1;
string_type str2;
str1 = coll_c.transform(strlit1, strlit1 + 3);
str2 = coll_c.transform(strlit2, strlit2 + 3);
i = str1.compare(str2);
VERIFY( i < 0 );
str1 = coll_de.transform(strlit1, strlit1 + 3);
str2 = coll_de.transform(strlit2, strlit2 + 3);
i = str1.compare(str2);
VERIFY( i < 0 );
str1 = coll_c.transform(strlit3, strlit3 + 3);
str2 = coll_c.transform(strlit4, strlit4 + 3);
i = str1.compare(str2);
VERIFY( i > 0 );
str1 = coll_de.transform(strlit3, strlit3 + 3);
str2 = coll_de.transform(strlit4, strlit4 + 3);
i = str1.compare(str2);
VERIFY( i < 0 );
str1 = coll_c.transform(strlit1, strlit1 + 1);
str2 = coll_c.transform(strlit5, strlit5 + 1);
i = str1.compare(str2);
VERIFY( i == 0 );
str1 = coll_de.transform(strlit6, strlit6 + 3);
str2 = coll_de.transform(strlit1, strlit1 + 3);
i = str1.compare(str2);
VERIFY( i > 0 );
str1 = coll_c.transform(strlit1, strlit1 + 3);
str2 = coll_c.transform(strlit5, strlit5 + 3);
i = str1.compare(str2);
VERIFY( i < 0 );
}
int main()
{
test03();
return 0;
}

View File

@ -0,0 +1,93 @@
// 2003-02-24 Petur Runolfsson <peturr02@ru.is>
// Copyright (C) 2003 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 22.2.4.1.1 collate members
#include <locale>
#include <testsuite_hooks.h>
void test03()
{
using namespace std;
typedef std::collate<wchar_t>::string_type string_type;
bool test = true;
// basic construction
locale loc_c = locale::classic();
locale loc_de("de_DE");
VERIFY( loc_c != loc_de );
// cache the collate facets
const collate<wchar_t>& coll_c = use_facet<collate<wchar_t> >(loc_c);
const collate<wchar_t>& coll_de = use_facet<collate<wchar_t> >(loc_de);
const wchar_t* strlit1 = L"a\0a\0";
const wchar_t* strlit2 = L"a\0b\0";
const wchar_t* strlit3 = L"a\0\xc4\0";
const wchar_t* strlit4 = L"a\0B\0";
const wchar_t* strlit5 = L"aa\0";
const wchar_t* strlit6 = L"b\0a\0";
int i;
string_type str1;
string_type str2;
str1 = coll_c.transform(strlit1, strlit1 + 3);
str2 = coll_c.transform(strlit2, strlit2 + 3);
i = str1.compare(str2);
VERIFY( i < 0 );
str1 = coll_de.transform(strlit1, strlit1 + 3);
str2 = coll_de.transform(strlit2, strlit2 + 3);
i = str1.compare(str2);
VERIFY( i < 0 );
str1 = coll_c.transform(strlit3, strlit3 + 3);
str2 = coll_c.transform(strlit4, strlit4 + 3);
i = str1.compare(str2);
VERIFY( i > 0 );
str1 = coll_de.transform(strlit3, strlit3 + 3);
str2 = coll_de.transform(strlit4, strlit4 + 3);
i = str1.compare(str2);
VERIFY( i < 0 );
str1 = coll_c.transform(strlit1, strlit1 + 1);
str2 = coll_c.transform(strlit5, strlit5 + 1);
i = str1.compare(str2);
VERIFY( i == 0 );
str1 = coll_de.transform(strlit6, strlit6 + 3);
str2 = coll_de.transform(strlit1, strlit1 + 3);
i = str1.compare(str2);
VERIFY( i > 0 );
str1 = coll_c.transform(strlit1, strlit1 + 3);
str2 = coll_c.transform(strlit5, strlit5 + 3);
i = str1.compare(str2);
VERIFY( i < 0 );
}
int main()
{
test03();
return 0;
}