From 3039874b15c391cc2a793abcfa3c2ef1f73844c9 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Tue, 19 Mar 2002 00:11:57 +0100 Subject: [PATCH] locale_facets.tcc (money_put::do_put(long double)): Fix dimensioning of temporary buffers to avoid risk of overruns. 2002-03-18 Paolo Carlini * 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 | 13 ++++++++ libstdc++-v3/include/bits/locale_facets.tcc | 16 +++++----- .../22_locale/money_put_members_char.cc | 30 ++++++++++++++++++- .../22_locale/money_put_members_wchar_t.cc | 30 ++++++++++++++++++- 4 files changed, 80 insertions(+), 9 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 92dfd018bfb..0377185a2ef 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,16 @@ +2002-03-18 Paolo Carlini + + * 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 * 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 37ad6b348cb..f2a1789f6e1 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 >(__loc); - const int __n = numeric_limits::digits10; + const ctype<_CharT>& __ctype = use_facet >(__loc); + // max_exponent10 + 1 for the integer part, + 4 for sign, decimal point, + // decimal digit, '\0'. + const int __n = numeric_limits::max_exponent10 + 5; char* __cs = static_cast(__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::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 c894b1851ac..a97f78fc8d6 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_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 OutIt; + + locale loc(locale::classic(), new My_money_io_2); + + bool intl = false; + + long double val = 1e50L; + const money_put& mp = + use_facet >(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 09feadd7a9d..dc77d0a0504 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 +{ + 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 OutIt; + + locale loc(locale::classic(), new My_money_io_2); + + bool intl = false; + + long double val = 1e50L; + const money_put& mp = + use_facet >(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; } -- 2.30.2