public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
* Re: libstdc++/3720 is a 2.95 regression [PATCH]
@ 2001-08-24 8:26 Philip Martin
0 siblings, 0 replies; only message in thread
From: Philip Martin @ 2001-08-24 8:26 UTC (permalink / raw)
To: nobody; +Cc: gcc-prs
The following reply was made to PR libstdc++/3720; it has been noted by GNATS.
From: Philip Martin <philip_martin@ntlworld.com>
To: gcc-gnats@gcc.gnu.org, gcc-prs@gcc.gnu.org, gcc-bugs@gcc.gnu.org, schmid@snake.iap.physik.tu-darmstadt.de, gcc-patches@gcc.gnu.org, libstdc++@gcc.gnu.org
Cc:
Subject: Re: libstdc++/3720 is a 2.95 regression [PATCH]
Date: 24 Aug 2001 16:16:03 +0100
A core dump caused by a buffer overflow in num_get::_M_extract(). This
affects all arithmetic input, making it impossible to write a robust
program that accepts numerical input without writing ones own number
parsing code. The simple program
#include <iostream>
int main()
{
int i;
std::cin >> i;
}
will cause a buffer overflow if the input stream contains more than 31
non-zero digits.
The following patch against the 3.0 branch replaces the fixed size
char array, with a std::vector<char>.
Philip
Index: ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/ChangeLog,v
retrieving revision 1.452.2.155
diff -c -3 -p -r1.452.2.155 ChangeLog
*** ChangeLog 2001/08/19 21:08:35 1.452.2.155
--- ChangeLog 2001/08/24 15:02:36
***************
*** 1,3 ****
--- 1,12 ----
+ 2001-08-24 Philip Martin <philip_martin@ntlworld.com>
+
+ libstdc++/3720
+ * include/bits/locale_facets.h: Replace char array with vector
+ * include/bits/locale_facets.tcc: Likewise
+ * src/locale.cc: Likewise
+ * src/locale-inst.cc: Add vector::_M_insert_aux explict instantiation
+ * testsuite/27_io/istream_extractor_arith.cc: Add test12 for excess input
+
2001-08-19 Release Manager
* GCC 3.0.1 Released.
Index: include/bits/locale_facets.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/locale_facets.h,v
retrieving revision 1.12.2.2
diff -c -3 -p -r1.12.2.2 locale_facets.h
*** locale_facets.h 2001/06/04 19:30:55 1.12.2.2
--- locale_facets.h 2001/08/24 15:02:37
***************
*** 40,45 ****
--- 40,46 ----
#include <bits/std_ctime.h> // For struct tm
#include <bits/std_ios.h> // For ios_base
+ #include <bits/std_vector.h> // For vector
#ifdef _GLIBCPP_USE_WCHAR_T
# include <langinfo.h> // For codecvt
# include <bits/std_cwctype.h> // For wctype_t
*************** namespace std
*** 655,661 ****
// NB: This is specialized for char.
void
_M_extract(iter_type __beg, iter_type __end, ios_base& __io,
! ios_base::iostate& __err, char* __xtrc,
int& __base, bool __fp = true) const;
virtual iter_type
--- 656,662 ----
// NB: This is specialized for char.
void
_M_extract(iter_type __beg, iter_type __end, ios_base& __io,
! ios_base::iostate& __err, vector<char>& __xtrc,
int& __base, bool __fp = true) const;
virtual iter_type
*************** namespace std
*** 714,720 ****
num_get<char, istreambuf_iterator<char> >::
_M_extract(istreambuf_iterator<char> __beg,
istreambuf_iterator<char> __end, ios_base& __io,
! ios_base::iostate& __err, char* __xtrc,
int& __base, bool __fp) const;
// _Numeric_put is used by num_put, money_put, and time_put
--- 715,721 ----
num_get<char, istreambuf_iterator<char> >::
_M_extract(istreambuf_iterator<char> __beg,
istreambuf_iterator<char> __end, ios_base& __io,
! ios_base::iostate& __err, vector<char>& __xtrc,
int& __base, bool __fp) const;
// _Numeric_put is used by num_put, money_put, and time_put
Index: include/bits/locale_facets.tcc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/locale_facets.tcc,v
retrieving revision 1.8.2.4
diff -c -3 -p -r1.8.2.4 locale_facets.tcc
*** locale_facets.tcc 2001/06/10 23:41:55 1.8.2.4
--- locale_facets.tcc 2001/08/24 15:02:38
*************** namespace std
*** 233,239 ****
// strto[l,ll,f,d]. The thought was to encapsulate the conversion
// into this one function, and thus the num_get::do_get member
// functions can just adjust for the type of the overloaded
! // argument and process the char array returned from _M_extract.
// Other things were also considered, including a fused
// multiply-add loop that would obviate the need for any call to
// strto... at all: however, it would b e a bit of a pain, because
--- 233,239 ----
// strto[l,ll,f,d]. The thought was to encapsulate the conversion
// into this one function, and thus the num_get::do_get member
// functions can just adjust for the type of the overloaded
! // argument and process the vector of char produced by _M_extract.
// Other things were also considered, including a fused
// multiply-add loop that would obviate the need for any call to
// strto... at all: however, it would b e a bit of a pain, because
*************** namespace std
*** 251,257 ****
void
num_get<_CharT, _InIter>::
_M_extract(_InIter /*__beg*/, _InIter /*__end*/, ios_base& /*__io*/,
! ios_base::iostate& /*__err*/, char* /*__xtrc*/,
int& /*__base*/, bool /*__fp*/) const
{
// XXX Not currently done: need to expand upon char version below.
--- 251,257 ----
void
num_get<_CharT, _InIter>::
_M_extract(_InIter /*__beg*/, _InIter /*__end*/, ios_base& /*__io*/,
! ios_base::iostate& /*__err*/, vector<char>& /*__xtrc*/,
int& /*__base*/, bool /*__fp*/) const
{
// XXX Not currently done: need to expand upon char version below.
*************** namespace std
*** 262,268 ****
num_get<char, istreambuf_iterator<char> >::
_M_extract(istreambuf_iterator<char> __beg,
istreambuf_iterator<char> __end, ios_base& __io,
! ios_base::iostate& __err, char* __xtrc, int& __base,
bool __fp) const;
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
--- 262,268 ----
num_get<char, istreambuf_iterator<char> >::
_M_extract(istreambuf_iterator<char> __beg,
istreambuf_iterator<char> __end, ios_base& __io,
! ios_base::iostate& __err, vector<char>& __xtrc, int& __base,
bool __fp) const;
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
*************** namespace std
*** 282,298 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[32] = {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
! long __l = strtol(__xtrc, &__sanity, __base);
if (!(__err & ios_base::failbit)
&& __l <= 1
! && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
__v = __l;
else
__err |= ios_base::failbit;
--- 282,299 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! vector<char> __xtrc;
! __xtrc.reserve(32);
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
! long __l = strtol(&__xtrc[0], &__sanity, __base);
if (!(__err & ios_base::failbit)
&& __l <= 1
! && __sanity != &__xtrc[0] && *__sanity == '\0' && errno == 0)
__v = __l;
else
__err |= ios_base::failbit;
*************** namespace std
*** 347,362 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[32]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
! long __l = strtol(__xtrc, &__sanity, __base);
if (!(__err & ios_base::failbit)
! && __sanity != __xtrc && *__sanity == '\0' && errno == 0
&& __l >= SHRT_MIN && __l <= SHRT_MAX)
__v = static_cast<short>(__l);
else
--- 348,364 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! vector<char> __xtrc;
! __xtrc.reserve(32);
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
! long __l = strtol(&__xtrc[0], &__sanity, __base);
if (!(__err & ios_base::failbit)
! && __sanity != &__xtrc[0] && *__sanity == '\0' && errno == 0
&& __l >= SHRT_MIN && __l <= SHRT_MAX)
__v = static_cast<short>(__l);
else
*************** namespace std
*** 374,389 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[32] = {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
! long __l = strtol(__xtrc, &__sanity, __base);
if (!(__err & ios_base::failbit)
! && __sanity != __xtrc && *__sanity == '\0' && errno == 0
&& __l >= INT_MIN && __l <= INT_MAX)
__v = static_cast<int>(__l);
else
--- 376,392 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! vector<char> __xtrc;
! __xtrc.reserve(32);
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
! long __l = strtol(&__xtrc[0], &__sanity, __base);
if (!(__err & ios_base::failbit)
! && __sanity != &__xtrc[0] && *__sanity == '\0' && errno == 0
&& __l >= INT_MIN && __l <= INT_MAX)
__v = static_cast<int>(__l);
else
*************** namespace std
*** 402,417 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[32]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
! long __l = strtol(__xtrc, &__sanity, __base);
if (!(__err & ios_base::failbit)
! && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
__v = __l;
else
__err |= ios_base::failbit;
--- 405,421 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! vector<char> __xtrc;
! __xtrc.reserve(32);
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
! long __l = strtol(&__xtrc[0], &__sanity, __base);
if (!(__err & ios_base::failbit)
! && __sanity != &__xtrc[0] && *__sanity == '\0' && errno == 0)
__v = __l;
else
__err |= ios_base::failbit;
*************** namespace std
*** 429,444 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[32]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
! long long __ll = strtoll(__xtrc, &__sanity, __base);
if (!(__err & ios_base::failbit)
! && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
__v = __ll;
else
__err |= ios_base::failbit;
--- 433,449 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! vector<char> __xtrc;
! __xtrc.reserve(32);
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
! long long __ll = strtoll(&__xtrc[0], &__sanity, __base);
if (!(__err & ios_base::failbit)
! && __sanity != &__xtrc[0] && *__sanity == '\0' && errno == 0)
__v = __ll;
else
__err |= ios_base::failbit;
*************** namespace std
*** 456,471 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[32]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
! unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
if (!(__err & ios_base::failbit)
! && __sanity != __xtrc && *__sanity == '\0' && errno == 0
&& __ul <= USHRT_MAX)
__v = static_cast<unsigned short>(__ul);
else
--- 461,477 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! vector<char> __xtrc;
! __xtrc.reserve(32);
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
! unsigned long __ul = strtoul(&__xtrc[0], &__sanity, __base);
if (!(__err & ios_base::failbit)
! && __sanity != &__xtrc[0] && *__sanity == '\0' && errno == 0
&& __ul <= USHRT_MAX)
__v = static_cast<unsigned short>(__ul);
else
*************** namespace std
*** 483,498 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[32]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
! unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
if (!(__err & ios_base::failbit)
! && __sanity != __xtrc && *__sanity == '\0' && errno == 0
&& __ul <= UINT_MAX)
__v = static_cast<unsigned int>(__ul);
else
--- 489,505 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! vector<char> __xtrc;
! __xtrc.reserve(32);
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
! unsigned long __ul = strtoul(&__xtrc[0], &__sanity, __base);
if (!(__err & ios_base::failbit)
! && __sanity != &__xtrc[0] && *__sanity == '\0' && errno == 0
&& __ul <= UINT_MAX)
__v = static_cast<unsigned int>(__ul);
else
*************** namespace std
*** 510,525 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[32] = {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
! unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
if (!(__err & ios_base::failbit)
! && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
__v = __ul;
else
__err |= ios_base::failbit;
--- 517,533 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! vector<char> __xtrc;
! __xtrc.reserve(32);
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
! unsigned long __ul = strtoul(&__xtrc[0], &__sanity, __base);
if (!(__err & ios_base::failbit)
! && __sanity != &__xtrc[0] && *__sanity == '\0' && errno == 0)
__v = __ul;
else
__err |= ios_base::failbit;
*************** namespace std
*** 537,552 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[32]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
! unsigned long long __ull = strtoull(__xtrc, &__sanity, __base);
if (!(__err & ios_base::failbit)
! && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
__v = __ull;
else
__err |= ios_base::failbit;
--- 545,561 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! vector<char> __xtrc;
! __xtrc.reserve(32);
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
! unsigned long long __ull = strtoull(&__xtrc[0], &__sanity, __base);
if (!(__err & ios_base::failbit)
! && __sanity != &__xtrc[0] && *__sanity == '\0' && errno == 0)
__v = __ull;
else
__err |= ios_base::failbit;
*************** namespace std
*** 564,570 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 256 for
// floating-point types.
! char __xtrc[32]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
--- 573,580 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 256 for
// floating-point types.
! vector<char> __xtrc;
! __xtrc.reserve(256);
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
*************** namespace std
*** 572,583 ****
char* __sanity;
errno = 0;
#ifdef _GLIBCPP_USE_C99
! float __f = strtof(__xtrc, &__sanity);
#else
! float __f = static_cast<float>(strtod(__xtrc, &__sanity));
#endif
if (!(__err & ios_base::failbit)
! && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
__v = __f;
else
__err |= ios_base::failbit;
--- 582,593 ----
char* __sanity;
errno = 0;
#ifdef _GLIBCPP_USE_C99
! float __f = strtof(&__xtrc[0], &__sanity);
#else
! float __f = static_cast<float>(strtod(&__xtrc[0], &__sanity));
#endif
if (!(__err & ios_base::failbit)
! && __sanity != &__xtrc[0] && *__sanity == '\0' && errno == 0)
__v = __f;
else
__err |= ios_base::failbit;
*************** namespace std
*** 594,609 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 256 for
// floating-point types.
! char __xtrc[32]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
! double __d = strtod(__xtrc, &__sanity);
if (!(__err & ios_base::failbit)
! && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
__v = __d;
else
__err |= ios_base::failbit;
--- 604,620 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 256 for
// floating-point types.
! vector<char> __xtrc;
! __xtrc.reserve(256);
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
! double __d = strtod(&__xtrc[0], &__sanity);
if (!(__err & ios_base::failbit)
! && __sanity != &__xtrc[0] && *__sanity == '\0' && errno == 0)
__v = __d;
else
__err |= ios_base::failbit;
*************** namespace std
*** 621,636 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 256 for
// floating-point types.
! char __xtrc[32]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
! long double __ld = strtold(__xtrc, &__sanity);
if (!(__err & ios_base::failbit)
! && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
__v = __ld;
else
__err |= ios_base::failbit;
--- 632,648 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 256 for
// floating-point types.
! vector<char> __xtrc;
! __xtrc.reserve(256);
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
! long double __ld = strtold(&__xtrc[0], &__sanity);
if (!(__err & ios_base::failbit)
! && __sanity != &__xtrc[0] && *__sanity == '\0' && errno == 0)
__v = __ld;
else
__err |= ios_base::failbit;
*************** namespace std
*** 645,651 ****
ios_base::iostate& __err, long double& __v) const
{
// Stage 1: extract
! char __xtrc[32]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
--- 657,664 ----
ios_base::iostate& __err, long double& __v) const
{
// Stage 1: extract
! vector<char> __xtrc;
! __xtrc.reserve(32);
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
*************** namespace std
*** 663,669 ****
// Stage 3: store results.
long double __ld;
! int __p = sscanf(__xtrc, __conv, &__ld);
if (__p
&& static_cast<typename __traits_type::int_type>(__p)
!= __traits_type::eof())
--- 676,682 ----
// Stage 3: store results.
long double __ld;
! int __p = sscanf(&__xtrc[0], __conv, &__ld);
if (__p
&& static_cast<typename __traits_type::int_type>(__p)
!= __traits_type::eof())
*************** namespace std
*** 691,706 ****
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! char __xtrc[32]= {'\0'};
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
! void* __vp = reinterpret_cast<void*>(strtoul(__xtrc, &__sanity, __base));
if (!(__err & ios_base::failbit)
! && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
__v = __vp;
else
__err |= ios_base::failbit;
--- 704,721 ----
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
! vector<char> __xtrc;
! __xtrc.reserve(32);
int __base;
_M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
! void* __vp = reinterpret_cast<void*>(strtoul(&__xtrc[0], &__sanity,
! __base));
if (!(__err & ios_base::failbit)
! && __sanity != &__xtrc[0] && *__sanity == '\0' && errno == 0)
__v = __vp;
else
__err |= ios_base::failbit;
Index: src/locale-inst.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/src/locale-inst.cc,v
retrieving revision 1.15.2.3
diff -c -3 -p -r1.15.2.3 locale-inst.cc
*** locale-inst.cc 2001/05/31 12:41:47 1.15.2.3
--- locale-inst.cc 2001/08/24 15:02:38
*************** namespace std
*** 319,323 ****
--- 319,330 ----
fill(__normal_iterator<locale::facet**, vector<locale::facet*> >,
__normal_iterator<locale::facet**, vector<locale::facet*> >,
locale::facet* const&);
+
+ template
+ void
+ std::vector<char>::_M_insert_aux(
+ std::__normal_iterator<char*, std::vector<char, std::allocator<char> > >,
+ char const&);
+
} // namespace std
Index: src/locale.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/src/locale.cc,v
retrieving revision 1.28.2.4
diff -c -3 -p -r1.28.2.4 locale.cc
*** locale.cc 2001/07/20 00:14:10 1.28.2.4
--- locale.cc 2001/08/24 15:02:39
*************** namespace std
*** 651,664 ****
num_get<char, istreambuf_iterator<char> >::
_M_extract(istreambuf_iterator<char> __beg,
istreambuf_iterator<char> __end, ios_base& __io,
! ios_base::iostate& __err, char* __xtrc, int& __base,
bool __fp) const
{
typedef _Format_cache<char> __cache_type;
- // Prepare for possible failure
- __xtrc[0] = '\0';
-
// Stage 1: determine a conversion specifier.
ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
if (__basefield == ios_base::dec)
--- 651,661 ----
num_get<char, istreambuf_iterator<char> >::
_M_extract(istreambuf_iterator<char> __beg,
istreambuf_iterator<char> __end, ios_base& __io,
! ios_base::iostate& __err, vector<char>& __xtrc, int& __base,
bool __fp) const
{
typedef _Format_cache<char> __cache_type;
// Stage 1: determine a conversion specifier.
ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
if (__basefield == ios_base::dec)
*************** namespace std
*** 680,685 ****
--- 677,683 ----
// Fail quickly if !__valid
if (__beg == __end)
{
+ __xtrc.push_back('\0');
__err |= (ios_base::eofbit | ios_base::failbit);
return;
}
*************** namespace std
*** 687,693 ****
// Acceptable formats for numbers here are based on 22.2.3.1
string __grp;
int __sep_pos = 0;
- int __pos = 0;
const char* __lits = __fmt->_S_literals;
char __c = *__beg;
--- 685,690 ----
*************** namespace std
*** 697,703 ****
|| (__c == __lits[__cache_type::_S_plus]))
{
__testsign = true;
! __xtrc[__pos++] = __c;
++__beg;
__c = * __beg;
--- 694,700 ----
|| (__c == __lits[__cache_type::_S_plus]))
{
__testsign = true;
! __xtrc.push_back(__c);
++__beg;
__c = * __beg;
*************** namespace std
*** 711,717 ****
// There had better be more to come...
if (__beg == __end)
{
! __xtrc[__pos] = '\0';
__err |= (ios_base::eofbit | ios_base::failbit);
return;
}
--- 708,714 ----
// There had better be more to come...
if (__beg == __end)
{
! __xtrc.push_back('\0');
__err |= (ios_base::eofbit | ios_base::failbit);
return;
}
*************** namespace std
*** 729,736 ****
// a plain '0' (possibly with a sign) can be got rid of now
if (__beg == __end)
{
! __xtrc[__pos++] = __lits[__cache_type::_S_digits];
! __xtrc[__pos] = '\0';
__err |= ios_base::eofbit;
return;
}
--- 726,733 ----
// a plain '0' (possibly with a sign) can be got rid of now
if (__beg == __end)
{
! __xtrc.push_back(__lits[__cache_type::_S_digits]);
! __xtrc.push_back('\0');
__err |= ios_base::eofbit;
return;
}
*************** namespace std
*** 784,790 ****
&& __p < &__lits[__cache_type::_S_udigits + __base])))
{
// Try first for acceptable digit; record it if found.
! __xtrc[__pos++] = __c;
++__sep_pos;
__testunits = true;
++__beg;
--- 781,787 ----
&& __p < &__lits[__cache_type::_S_udigits + __base])))
{
// Try first for acceptable digit; record it if found.
! __xtrc.push_back(__c);
++__sep_pos;
__testunits = true;
++__beg;
*************** namespace std
*** 844,850 ****
if (!__test)
{
__err |= ios_base::failbit;
! __xtrc[__pos] = '\0';
if (__beg == __end)
__err |= ios_base::eofbit;
return;
--- 841,847 ----
if (!__test)
{
__err |= ios_base::failbit;
! __xtrc.push_back('\0');
if (__beg == __end)
__err |= ios_base::eofbit;
return;
*************** namespace std
*** 852,859 ****
}
// If there was nothing but zeros, put one in the output string
! if (__testzero && (__pos == 0 || (__pos == 1 && __testsign)))
! __xtrc[__pos++] = __lits[__cache_type::_S_digits];
// That's it for integer types. Remaining code is for floating point
if (__fp && __beg != __end)
--- 849,857 ----
}
// If there was nothing but zeros, put one in the output string
! if (__testzero && (__xtrc.size() == 0
! || (__xtrc.size() == 1 && __testsign)))
! __xtrc.push_back(__lits[__cache_type::_S_digits]);
// That's it for integer types. Remaining code is for floating point
if (__fp && __beg != __end)
*************** namespace std
*** 864,870 ****
// with digits following it?
if (__c == __fmt->_M_decimal_point)
{
! __xtrc[__pos++] = '.';
++__beg;
__c = *__beg;
--- 862,868 ----
// with digits following it?
if (__c == __fmt->_M_decimal_point)
{
! __xtrc.push_back('.');
++__beg;
__c = *__beg;
*************** namespace std
*** 878,884 ****
|| (__p >= &__lits[__cache_type::_S_udigits]
&& __p < &__lits[__cache_type::_S_udigits + __base]))
{
! __xtrc[__pos++] = __c;
++__beg;
__c = *__beg;
__testdec = true;
--- 876,882 ----
|| (__p >= &__lits[__cache_type::_S_udigits]
&& __p < &__lits[__cache_type::_S_udigits + __base]))
{
! __xtrc.push_back(__c);
++__beg;
__c = *__beg;
__testdec = true;
*************** namespace std
*** 890,896 ****
if (!__testunits && !__testdec) // Ill formed
{
__err |= ios_base::failbit;
! __xtrc[__pos] = '\0';
if (__beg == __end)
__err |= ios_base::eofbit;
return;
--- 888,894 ----
if (!__testunits && !__testdec) // Ill formed
{
__err |= ios_base::failbit;
! __xtrc.push_back('\0');
if (__beg == __end)
__err |= ios_base::eofbit;
return;
*************** namespace std
*** 902,908 ****
if ((__c == __lits[__cache_type::_S_ee])
|| (__c == __lits[__cache_type::_S_Ee]))
{
! __xtrc[__pos++] = __c;
++__beg;
__c = *__beg;
--- 900,906 ----
if ((__c == __lits[__cache_type::_S_ee])
|| (__c == __lits[__cache_type::_S_Ee]))
{
! __xtrc.push_back(__c);
++__beg;
__c = *__beg;
*************** namespace std
*** 912,918 ****
if ((__c == __lits[__cache_type::_S_minus])
|| (__c == __lits[__cache_type::_S_plus]))
{
! __xtrc[__pos++] = __c;
++__beg;
__c = *__beg;
// whitespace may follow a sign
--- 910,916 ----
if ((__c == __lits[__cache_type::_S_minus])
|| (__c == __lits[__cache_type::_S_plus]))
{
! __xtrc.push_back(__c);
++__beg;
__c = *__beg;
// whitespace may follow a sign
*************** namespace std
*** 926,932 ****
// And now there must be some digits
if (__beg == __end)
{
! __xtrc[__pos] = '\0';
__err |= (ios_base::eofbit | ios_base::failbit);
return;
}
--- 924,930 ----
// And now there must be some digits
if (__beg == __end)
{
! __xtrc.push_back('\0');
__err |= (ios_base::eofbit | ios_base::failbit);
return;
}
*************** namespace std
*** 938,944 ****
|| (__p >= &__lits[__cache_type::_S_udigits]
&& __p < &__lits[__cache_type::_S_udigits + __base]))
{
! __xtrc[__pos++] = __c;
++__beg;
__c = *__beg;
}
--- 936,942 ----
|| (__p >= &__lits[__cache_type::_S_udigits]
&& __p < &__lits[__cache_type::_S_udigits + __base]))
{
! __xtrc.push_back(__c);
++__beg;
__c = *__beg;
}
*************** namespace std
*** 951,957 ****
}
// Finish up
! __xtrc[__pos] = '\0';
if (__beg == __end)
__err |= ios_base::eofbit;
}
--- 949,955 ----
}
// Finish up
! __xtrc.push_back('\0');
if (__beg == __end)
__err |= ios_base::eofbit;
}
Index: testsuite/27_io/istream_extractor_arith.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/27_io/istream_extractor_arith.cc,v
retrieving revision 1.8.4.1
diff -c -3 -p -r1.8.4.1 istream_extractor_arith.cc
*** istream_extractor_arith.cc 2001/05/14 19:49:23 1.8.4.1
--- istream_extractor_arith.cc 2001/08/24 15:02:39
*************** bool test11()
*** 513,518 ****
--- 513,552 ----
return test;
}
+ // libstdc++/3720
+ // excess input should not cause a core dump
+ template<typename T>
+ bool test12_aux()
+ {
+ bool test = true;
+
+ // this many digits will overflow
+ int digits_overflow = std::numeric_limits<long double>::max_exponent10 + 1;
+
+ std::string st;
+ std::string part = "1234567890123456789012345678901234567890";
+ for (int i = 0; i < digits_overflow / part.size() + 1; ++i)
+ st += part;
+ std::stringbuf sb(st);
+ std::istream is(&sb);
+ T t;
+ is >> t;
+ VERIFY(is.fail());
+ return test;
+ }
+
+ bool test12()
+ {
+ bool test = true;
+ VERIFY(test12_aux<short>());
+ VERIFY(test12_aux<int>());
+ VERIFY(test12_aux<long>());
+ VERIFY(test12_aux<float>());
+ VERIFY(test12_aux<double>());
+ VERIFY(test12_aux<long double>());
+ return test;
+ }
+
int main()
{
test01();
*************** int main()
*** 526,531 ****
--- 560,566 ----
test10();
test11();
+ test12();
return 0;
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2001-08-24 8:26 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-08-24 8:26 libstdc++/3720 is a 2.95 regression [PATCH] Philip Martin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).