]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR libstdc++/39168 (Incorrect interpretation of CHAR_MAX inside grouping string...
authorPaolo Carlini <paolo.carlini@oracle.com>
Sun, 15 Feb 2009 16:47:57 +0000 (16:47 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Sun, 15 Feb 2009 16:47:57 +0000 (16:47 +0000)
2009-02-15  Paolo Carlini  <paolo.carlini@oracle.com>

PR libstdc++/39168
* src/locale_facets.cc (__verify_grouping(const char*, size_t,
const string&)): Also check that the value != CHAR_MAX.
* include/bits/locale_facets.tcc (__numpunct_cache<>::
_M_cache(const locale&), __add_grouping(_CharT*, _CharT,
const char*, size_t, const _CharT*, const _CharT*)): Likewise.
* include/bits/locale_facets_nonio.tcc (__moneypunct_cache<>::
_M_cache(const locale&)): Likewise.
* testsuite/22_locale/money_put/put/wchar_t/39168.cc: New.
* testsuite/22_locale/money_put/put/char/39168.cc: Likewise.
* testsuite/22_locale/money_get/get/wchar_t/39168.cc: Likewise.
* testsuite/22_locale/money_get/get/char/39168.cc: Likewise.
* testsuite/22_locale/num_get/get/wchar_t/39168.cc: Likewise.
* testsuite/22_locale/num_get/get/char/39168.cc: Likewise.

From-SVN: r144190

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/locale_facets.tcc
libstdc++-v3/include/bits/locale_facets_nonio.tcc
libstdc++-v3/src/locale_facets.cc
libstdc++-v3/testsuite/22_locale/money_get/get/char/39168.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/money_get/get/wchar_t/39168.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/money_put/put/char/39168.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/money_put/put/wchar_t/39168.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/num_get/get/char/39168.cc [new file with mode: 0644]
libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/39168.cc [new file with mode: 0644]

index c8d9d410926d2d78571dfaee7aa9d049e8c19837..96c79056dcdc91034a56e03d1572dc10d710b77e 100644 (file)
@@ -1,3 +1,20 @@
+2009-02-15  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR libstdc++/39168
+       * src/locale_facets.cc (__verify_grouping(const char*, size_t,
+       const string&)): Also check that the value != CHAR_MAX.
+       * include/bits/locale_facets.tcc (__numpunct_cache<>::
+       _M_cache(const locale&), __add_grouping(_CharT*, _CharT,
+       const char*, size_t, const _CharT*, const _CharT*)): Likewise.
+       * include/bits/locale_facets_nonio.tcc (__moneypunct_cache<>::
+       _M_cache(const locale&)): Likewise.
+       * testsuite/22_locale/money_put/put/wchar_t/39168.cc: New.
+       * testsuite/22_locale/money_put/put/char/39168.cc: Likewise.
+       * testsuite/22_locale/money_get/get/wchar_t/39168.cc: Likewise.
+       * testsuite/22_locale/money_get/get/char/39168.cc: Likewise.
+       * testsuite/22_locale/num_get/get/wchar_t/39168.cc: Likewise.
+       * testsuite/22_locale/num_get/get/char/39168.cc: Likewise.
+
 2009-02-13  Chris Fairles  <cfairles@gcc.gnu.org>
            Benjamin Kosnik  <bkoz@redhat.com>
 
index 779b4d505e149f11a95aea2af7d389c281275d5e..93bc6d48366078cf47e7b63bc45e34a0dee07bef 100644 (file)
@@ -91,7 +91,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
       __np.grouping().copy(__grouping, _M_grouping_size);
       _M_grouping = __grouping;
       _M_use_grouping = (_M_grouping_size
-                        && static_cast<signed char>(__np.grouping()[0]) > 0);
+                        && static_cast<signed char>(_M_grouping[0]) > 0
+                        && (_M_grouping[0]
+                            != __gnu_cxx::__numeric_traits<char>::__max));
 
       _M_truename_size = __np.truename().size();
       _CharT* __truename = new _CharT[_M_truename_size];
@@ -1232,7 +1234,8 @@ _GLIBCXX_END_LDBL_NAMESPACE
       size_t __ctr = 0;
 
       while (__last - __first > __gbeg[__idx]
-            && static_cast<signed char>(__gbeg[__idx]) > 0)
+            && static_cast<signed char>(__gbeg[__idx]) > 0
+            && __gbeg[__idx] != __gnu_cxx::__numeric_traits<char>::__max)
        {
          __last -= __gbeg[__idx];
          __idx < __gsize - 1 ? ++__idx : ++__ctr;
index 9cc1b913d19c64ecf0e226c8716d551d8340b5bb..f32ad7fdb1df39bbf3fff465a9b9df2ff6f901f2 100644 (file)
@@ -81,8 +81,10 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
       __mp.grouping().copy(__grouping, _M_grouping_size);
       _M_grouping = __grouping;
       _M_use_grouping = (_M_grouping_size
-                        && static_cast<signed char>(__mp.grouping()[0]) > 0);
-      
+                        && static_cast<signed char>(_M_grouping[0]) > 0
+                        && (_M_grouping[0]
+                            != __gnu_cxx::__numeric_traits<char>::__max));
+
       _M_decimal_point = __mp.decimal_point();
       _M_thousands_sep = __mp.thousands_sep();
       _M_frac_digits = __mp.frac_digits();
index 89c7e497890b2b7ab7cbe822751365d48b18c1c9..d62fb04fcb61c6c318bd5bc16f4eb68d166b9329 100644 (file)
@@ -1,5 +1,5 @@
 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-// 2006, 2007
+// 2006, 2007, 2008, 2009
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -110,7 +110,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
     // ... 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)
+    if (static_cast<signed char>(__grouping[__min]) > 0
+       && __grouping[__min] != __gnu_cxx::__numeric_traits<char>::__max)
       __test &= __grouping_tmp[0] <= __grouping[__min];
     return __test;
   }
diff --git a/libstdc++-v3/testsuite/22_locale/money_get/get/char/39168.cc b/libstdc++-v3/testsuite/22_locale/money_get/get/char/39168.cc
new file mode 100644 (file)
index 0000000..45cc692
--- /dev/null
@@ -0,0 +1,57 @@
+// Copyright (C) 2009 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.6.1.1 money_get members
+
+#include <sstream>
+#include <locale>
+#include <climits>
+#include <testsuite_hooks.h>
+
+class my_moneypunct: public std::moneypunct<char>
+{
+protected:
+  std::string do_grouping() const { return std::string(1, CHAR_MAX); }
+};
+
+// libstdc++/39168
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+  typedef istreambuf_iterator<char> iterator_type;
+
+  istringstream iss;
+  iss.imbue(locale(iss.getloc(), new my_moneypunct));
+  const money_get<char>& mg = use_facet<money_get<char> >(iss.getloc());
+
+  string digits;
+  ios_base::iostate err = ios_base::goodbit;
+
+  iss.str("123,456");
+  iterator_type end = mg.get(iss.rdbuf(), 0, false, iss, err, digits);
+  VERIFY( err == ios_base::goodbit );
+  VERIFY( digits == "123" );
+  VERIFY( *end == ',' );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/money_get/get/wchar_t/39168.cc b/libstdc++-v3/testsuite/22_locale/money_get/get/wchar_t/39168.cc
new file mode 100644 (file)
index 0000000..44dd961
--- /dev/null
@@ -0,0 +1,57 @@
+// Copyright (C) 2009 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.6.1.1 money_get members
+
+#include <sstream>
+#include <locale>
+#include <climits>
+#include <testsuite_hooks.h>
+
+class my_moneypunct: public std::moneypunct<wchar_t>
+{
+protected:
+  std::string do_grouping() const { return std::string(1, CHAR_MAX); }
+};
+
+// libstdc++/39168
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+  typedef istreambuf_iterator<wchar_t> iterator_type;
+
+  wistringstream iss;
+  iss.imbue(locale(iss.getloc(), new my_moneypunct));
+  const money_get<wchar_t>& mg = use_facet<money_get<wchar_t> >(iss.getloc());
+
+  wstring digits;
+  ios_base::iostate err = ios_base::goodbit;
+
+  iss.str(L"123,456");
+  iterator_type end = mg.get(iss.rdbuf(), 0, false, iss, err, digits);
+  VERIFY( err == ios_base::goodbit );
+  VERIFY( digits == L"123" );
+  VERIFY( *end == L',' );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/money_put/put/char/39168.cc b/libstdc++-v3/testsuite/22_locale/money_put/put/char/39168.cc
new file mode 100644 (file)
index 0000000..1896933
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright (C) 2009 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.6.2.1 money_put members
+
+#include <sstream>
+#include <locale>
+#include <climits>
+#include <testsuite_hooks.h>
+
+class my_moneypunct: public std::moneypunct<char>
+{
+protected:
+  std::string do_grouping() const { return std::string(1, CHAR_MAX); }
+};
+
+// libstdc++/39168
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  ostringstream oss;
+  oss.imbue(locale(oss.getloc(), new my_moneypunct));
+  const money_put<char>& mp = use_facet<money_put<char> >(oss.getloc());
+
+  string digits(300, '1');
+  mp.put(oss.rdbuf(), false, oss, ' ', digits);
+  VERIFY( oss.str() == digits );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/money_put/put/wchar_t/39168.cc b/libstdc++-v3/testsuite/22_locale/money_put/put/wchar_t/39168.cc
new file mode 100644 (file)
index 0000000..c1e195b
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright (C) 2009 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.6.2.1 money_put members
+
+#include <sstream>
+#include <locale>
+#include <climits>
+#include <testsuite_hooks.h>
+
+class my_moneypunct: public std::moneypunct<wchar_t>
+{
+protected:
+  std::string do_grouping() const { return std::string(1, CHAR_MAX); }
+};
+
+// libstdc++/39168
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  wostringstream oss;
+  oss.imbue(locale(oss.getloc(), new my_moneypunct));
+  const money_put<wchar_t>& mp = use_facet<money_put<wchar_t> >(oss.getloc());
+
+  wstring digits(300, L'1');
+  mp.put(oss.rdbuf(), false, oss, ' ', digits);
+  VERIFY( oss.str() == digits );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/num_get/get/char/39168.cc b/libstdc++-v3/testsuite/22_locale/num_get/get/char/39168.cc
new file mode 100644 (file)
index 0000000..9f83e1a
--- /dev/null
@@ -0,0 +1,57 @@
+// Copyright (C) 2009 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 <sstream>
+#include <locale>
+#include <climits>
+#include <testsuite_hooks.h>
+
+class my_numpunct: public std::numpunct<char>
+{
+protected:
+  std::string do_grouping() const { return std::string(1, CHAR_MAX); }
+};
+
+// libstdc++/39168
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+  typedef istreambuf_iterator<char> iterator_type;
+
+  istringstream iss;
+  iss.imbue(locale(iss.getloc(), new my_numpunct));
+  const num_get<char>& ng = use_facet<num_get<char> >(iss.getloc());
+
+  long double l = -1;
+  ios_base::iostate err = ios_base::goodbit;
+
+  iss.str("123,456");
+  iterator_type end = ng.get(iss.rdbuf(), 0, iss, err, l);
+  VERIFY( err == ios_base::goodbit );
+  VERIFY( l == 123 );
+  VERIFY( *end == ',' );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/39168.cc b/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/39168.cc
new file mode 100644 (file)
index 0000000..aa1bbf2
--- /dev/null
@@ -0,0 +1,57 @@
+// Copyright (C) 2009 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 <sstream>
+#include <locale>
+#include <climits>
+#include <testsuite_hooks.h>
+
+class my_numpunct: public std::numpunct<wchar_t>
+{
+protected:
+  std::string do_grouping() const { return std::string(1, CHAR_MAX); }
+};
+
+// libstdc++/39168
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+  typedef istreambuf_iterator<wchar_t> iterator_type;
+
+  wistringstream iss;
+  iss.imbue(locale(iss.getloc(), new my_numpunct));
+  const num_get<wchar_t>& ng = use_facet<num_get<wchar_t> >(iss.getloc());
+
+  long double l = -1;
+  ios_base::iostate err = ios_base::goodbit;
+
+  iss.str(L"123,456");
+  iterator_type end = ng.get(iss.rdbuf(), 0, iss, err, l);
+  VERIFY( err == ios_base::goodbit );
+  VERIFY( l == 123 );
+  VERIFY( *end == L',' );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}