aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <pcarlini@unitus.it>2002-03-19 00:11:57 +0100
committerPaolo Carlini <paolo@gcc.gnu.org>2002-03-18 23:11:57 +0000
commit3039874b15c391cc2a793abcfa3c2ef1f73844c9 (patch)
tree94358cd6d79a6d009431d334b34e26e50b85c8d3
parent1929c971b93d72d109d796c9977f3943a64e1d7a (diff)
downloadgcc-3039874b15c391cc2a793abcfa3c2ef1f73844c9.zip
gcc-3039874b15c391cc2a793abcfa3c2ef1f73844c9.tar.gz
gcc-3039874b15c391cc2a793abcfa3c2ef1f73844c9.tar.bz2
locale_facets.tcc (money_put::do_put(long double)): Fix dimensioning of temporary buffers to avoid risk of overruns.
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
-rw-r--r--libstdc++-v3/ChangeLog13
-rw-r--r--libstdc++-v3/include/bits/locale_facets.tcc16
-rw-r--r--libstdc++-v3/testsuite/22_locale/money_put_members_char.cc30
-rw-r--r--libstdc++-v3/testsuite/22_locale/money_put_members_wchar_t.cc30
4 files changed, 80 insertions, 9 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 92dfd01..0377185 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -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.
diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc
index 37ad6b3..f2a1789 100644
--- a/libstdc++-v3/include/bits/locale_facets.tcc
+++ b/libstdc++-v3/include/bits/locale_facets.tcc
@@ -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);
}
diff --git a/libstdc++-v3/testsuite/22_locale/money_put_members_char.cc b/libstdc++-v3/testsuite/22_locale/money_put_members_char.cc
index c894b18..a97f78f 100644
--- a/libstdc++-v3/testsuite/22_locale/money_put_members_char.cc
+++ b/libstdc++-v3/testsuite/22_locale/money_put_members_char.cc
@@ -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;
}
diff --git a/libstdc++-v3/testsuite/22_locale/money_put_members_wchar_t.cc b/libstdc++-v3/testsuite/22_locale/money_put_members_wchar_t.cc
index 09feadd..dc77d0a 100644
--- a/libstdc++-v3/testsuite/22_locale/money_put_members_wchar_t.cc
+++ b/libstdc++-v3/testsuite/22_locale/money_put_members_wchar_t.cc
@@ -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;
}