locale_facets.tcc (money_put::do_put(long double)): Fix dimensioning of temporary...
authorPaolo Carlini <pcarlini@unitus.it>
Mon, 18 Mar 2002 23:11:57 +0000 (00:11 +0100)
committerPaolo Carlini <paolo@gcc.gnu.org>
Mon, 18 Mar 2002 23:11:57 +0000 (23:11 +0000)
2002-03-18  Paolo Carlini  <pcarlini@unitus.it>

* include/bits/locale_facets.tcc
(money_put::do_put(long double)): Fix dimensioning of
temporary buffers to avoid risk of overruns.
(money_put::do_put(string)): Same for the buffer used to
add the grouping chars.
* testsuite/22_locale/money_put_members_char.cc: Add test06.
* testsuite/22_locale/money_put_members_wchar_t.cc: Ditto.

* include/bits/locale_facets.tcc
(collate::do_transform): Simplify.

From-SVN: r51012

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/locale_facets.tcc
libstdc++-v3/testsuite/22_locale/money_put_members_char.cc
libstdc++-v3/testsuite/22_locale/money_put_members_wchar_t.cc

index 92dfd018bfbc8ddb0e80e416ee07c4cf6ac78dd3..0377185a2ef38fd6272175ccababf9e0448666b4 100644 (file)
@@ -1,3 +1,16 @@
+2002-03-18  Paolo Carlini  <pcarlini@unitus.it>
+
+       * include/bits/locale_facets.tcc
+       (money_put::do_put(long double)): Fix dimensioning of
+       temporary buffers to avoid risk of overruns.
+       (money_put::do_put(string)): Same for the buffer used to
+       add the grouping chars.
+       * testsuite/22_locale/money_put_members_char.cc: Add test06.
+       * testsuite/22_locale/money_put_members_wchar_t.cc: Ditto.
+
+       * include/bits/locale_facets.tcc
+       (collate::do_transform): Simplify.
+
 2002-03-18  Phil Edwards  <pme@gcc.gnu.org>
 
        * acinclude.m4 (GLIBCPP_CONFIGURE):  Make indentation/spacing uniform.
index 37ad6b348cb0b6e38b6e2bec9c298c81673851a1..f2a1789f6e165723d8fd0237f67bbcf6dd2846a2 100644 (file)
@@ -1110,8 +1110,10 @@ namespace std
           long double __units) const
     { 
       const locale __loc = __io.getloc();
-      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 
-      const int __n = numeric_limits<long double>::digits10;
+      const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+      // max_exponent10 + 1 for the integer part, + 4 for sign, decimal point,
+      // decimal digit, '\0'. 
+      const int __n = numeric_limits<long double>::max_exponent10 + 5;
       char* __cs = static_cast<char*>(__builtin_alloca(sizeof(char) * __n));
       _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
       int __len = __convert_from_v(__cs, "%.01Lf", __units, _S_c_locale);
@@ -1206,8 +1208,9 @@ namespace std
                                                 : __mpf.thousands_sep();
                  const char* __gbeg = __grouping.c_str();
                  const char* __gend = __gbeg + __grouping.size();
-                 const int __n = numeric_limits<long double>::digits10 * 2;
-                 _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
+                 const int __n = (__end - __beg) * 2;
+                 _CharT* __ws2 =
+                   static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
                  _CharT* __ws_end = __add_grouping(__ws2, __sep, __gbeg, 
                                                    __gend, __beg, __end);
                  __value.insert(0, __ws2, __ws_end - __ws2);
@@ -1863,10 +1866,9 @@ namespace std
       // If the buffer was not large enough, try again with the correct size.
       if (__res >= __len)
        {
-         _CharT* __c2 =
+         __c =
            static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * (__res + 1)));
-         _M_transform_helper(__c2, __lo, __res + 1);
-         return string_type(__c2);
+         _M_transform_helper(__c, __lo, __res + 1);
        }
       return string_type(__c);
     }
index c894b1851ac004f68392fee93b1c842fc4949e12..a97f78fc8d6d91f3e1631b62c6d9503d7ebc550c 100644 (file)
@@ -226,7 +226,7 @@ void test02()
   oss.setf(ios_base::showbase);
 
   oss.str(empty);
- iterator_type os_it03 = mon_put.put(oss.rdbuf(), true, oss, ' ', digits1);
 iterator_type os_it03 = mon_put.put(oss.rdbuf(), true, oss, ' ', digits1);
   string result3 = oss.str();
   VERIFY( result3 == "7.200.000.000,00 DEM ");
 
@@ -341,6 +341,33 @@ void test05()
   VERIFY( fmt.str() == "*(1,234.56)" );
 }
 
+struct My_money_io_2 : public std::moneypunct<char,false>
+{
+  char_type do_thousands_sep() const { return ','; }
+  std::string do_grouping() const { return "\001"; }
+};
+
+// Make sure we can output a very big amount of money (with grouping too).
+void test06()
+{
+  using namespace std;
+  typedef ostreambuf_iterator<char> OutIt;
+
+  locale loc(locale::classic(), new My_money_io_2);
+
+  bool intl = false;
+
+  long double val = 1e50L;
+  const money_put<char,OutIt>& mp  =
+    use_facet<money_put<char, OutIt> >(loc);
+
+  ostringstream fmt;
+  fmt.imbue(loc);
+  OutIt out(fmt);
+  mp.put(out,intl,fmt,'*',val);
+  VERIFY( fmt );
+}
+
 int main()
 {
   test01();
@@ -348,5 +375,6 @@ int main()
   test03();
   test04();
   test05();
+  test06();
   return 0;
 }
index 09feadd7a9df4eecf5fa39cc819694db9a2c2735..dc77d0a05044e8c5599f9295742364ff470bac26 100644 (file)
@@ -226,7 +226,7 @@ void test02()
   oss.setf(ios_base::showbase);
 
   oss.str(empty);
- iterator_type os_it03 = mon_put.put(oss.rdbuf(), true, oss, ' ', digits1);
 iterator_type os_it03 = mon_put.put(oss.rdbuf(), true, oss, ' ', digits1);
   wstring result3 = oss.str();
   VERIFY( result3 == L"7.200.000.000,00 DEM ");
 
@@ -340,6 +340,33 @@ void test05()
   mp.put(out,intl,fmt,L'*',val);
   VERIFY( fmt.str() == L"*(1,234.56)" );
 }
+
+struct My_money_io_2 : public std::moneypunct<wchar_t,false>
+{
+  char_type do_thousands_sep() const { return L','; }
+  std::string do_grouping() const { return "\001"; }
+};
+
+// Make sure we can output a very big amount of money (with grouping too).
+void test06()
+{
+  using namespace std;
+  typedef ostreambuf_iterator<wchar_t> OutIt;
+
+  locale loc(locale::classic(), new My_money_io_2);
+
+  bool intl = false;
+
+  long double val = 1e50L;
+  const money_put<wchar_t,OutIt>& mp  =
+    use_facet<money_put<wchar_t, OutIt> >(loc);
+
+  wostringstream fmt;
+  fmt.imbue(loc);
+  OutIt out(fmt);
+  mp.put(out,intl,fmt,'*',val);
+  VERIFY( fmt );
+}
 #endif
 
 int main()
@@ -350,6 +377,7 @@ int main()
   test03();
   test04();
   test05();
+  test06();
 #endif
   return 0;
 }