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).