This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix libstdc++/9817
- From: Pétur Runólfsson <peturr02 at ru dot is>
- To: <libstdc++ at gcc dot gnu dot org>
- Cc: <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 25 Feb 2003 07:54:28 -0000
- Subject: [PATCH] Fix libstdc++/9817
Hi,
This is the patch promised by Paolo yesterday :-)
Tested on linux on x86.
Petur
2003-02-24 Petur Runolfsson <peturr02 at ru dot 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.
Index: libstdc++-v3/include/bits/locale_facets.tcc
===================================================================
RCS file: /home/petur/cvsroot/gcc/libstdc++-v3/include/bits/locale_facets.tcc,v
retrieving revision 1.1.1.2
diff -c -3 -p -r1.1.1.2 locale_facets.tcc
*** libstdc++-v3/include/bits/locale_facets.tcc 22 Feb 2003 15:51:11 -0000 1.1.1.2
--- libstdc++-v3/include/bits/locale_facets.tcc 24 Feb 2003 19:45:02 -0000
*************** namespace std
*** 2038,2046 ****
do_compare(const _CharT* __lo1, const _CharT* __hi1,
const _CharT* __lo2, const _CharT* __hi2) const
{
const string_type __one(__lo1, __hi1);
const string_type __two(__lo2, __hi2);
! return _M_compare(__one.c_str(), __two.c_str());
}
template<typename _CharT>
--- 2038,2074 ----
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);
!
! 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>
*************** namespace std
*** 2048,2066 ****
collate<_CharT>::
do_transform(const _CharT* __lo, const _CharT* __hi) const
{
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)
{
! __c = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
! * (__res + 1)));
! _M_transform(__c, __lo, __res + 1);
}
- return string_type(__c);
}
template<typename _CharT>
--- 2076,2118 ----
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;
!
! 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 (;;)
{
! // 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());
}
}
template<typename _CharT>
Index: libstdc++-v3/testsuite/22_locale/collate/compare/char/3.cc
===================================================================
RCS file: libstdc++-v3/testsuite/22_locale/collate/compare/char/3.cc
diff -N libstdc++-v3/testsuite/22_locale/collate/compare/char/3.cc
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- libstdc++-v3/testsuite/22_locale/collate/compare/char/3.cc 24 Feb 2003 23:12:57 -0000
***************
*** 0 ****
--- 1,90 ----
+ // 2003-02-24 Petur Runolfsson <peturr02 at ru dot 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;
+ }
Index: libstdc++-v3/testsuite/22_locale/collate/compare/wchar_t/3.cc
===================================================================
RCS file: libstdc++-v3/testsuite/22_locale/collate/compare/wchar_t/3.cc
diff -N libstdc++-v3/testsuite/22_locale/collate/compare/wchar_t/3.cc
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- libstdc++-v3/testsuite/22_locale/collate/compare/wchar_t/3.cc 24 Feb 2003 23:19:21 -0000
***************
*** 0 ****
--- 1,90 ----
+ // 2003-02-24 Petur Runolfsson <peturr02 at ru dot 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;
+ }
Index: libstdc++-v3/testsuite/22_locale/collate/transform/char/3.cc
===================================================================
RCS file: libstdc++-v3/testsuite/22_locale/collate/transform/char/3.cc
diff -N libstdc++-v3/testsuite/22_locale/collate/transform/char/3.cc
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- libstdc++-v3/testsuite/22_locale/collate/transform/char/3.cc 24 Feb 2003 23:12:56 -0000
***************
*** 0 ****
--- 1,93 ----
+ // 2003-02-24 Petur Runolfsson <peturr02 at ru dot 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;
+ }
Index: libstdc++-v3/testsuite/22_locale/collate/transform/wchar_t/3.cc
===================================================================
RCS file: libstdc++-v3/testsuite/22_locale/collate/transform/wchar_t/3.cc
diff -N libstdc++-v3/testsuite/22_locale/collate/transform/wchar_t/3.cc
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- libstdc++-v3/testsuite/22_locale/collate/transform/wchar_t/3.cc 24 Feb 2003 23:19:22 -0000
***************
*** 0 ****
--- 1,93 ----
+ // 2003-02-24 Petur Runolfsson <peturr02 at ru dot 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;
+ }