This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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;
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]