This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[v3] Absolutely avoid integer overflow in istream::ignore


Hi,

also in the light of the ongoing discussion about aggressive loop
unrolling, I decided to remove an hack of mine which relied on an
infinite loop and integer overflow in order to deal correctly with
huge ignore (> 2G) on LFS-enbled 32-bit machines.

Tested x86-linux (tested the generic implementation too by disabling
the specializations).

Paolo.

//////////////
2005-01-02  Paolo Carlini  <pcarlini@suse.de>

	* src/istream.cc (basic_istream<char>::ignore(streamsize),
	basic_istream<char>::ignore(streamsize, int_type),
	basic_istream<wchar_t>::ignore(streamsize),
	basic_istream<wchar_t>::ignore(streamsize, int_type)): Avoid
	_M_gcount overflows. 	
	* include/bits/istream.tcc (ignore(streamsize), ignore(streamsize,
	int_type)): Likewise; use snextc in the main loop, consistently
	with the specializations above.
diff -prN libstdc++-v3-orig/include/bits/istream.tcc libstdc++-v3/include/bits/istream.tcc
*** libstdc++-v3-orig/include/bits/istream.tcc	Fri Nov 26 21:34:24 2004
--- libstdc++-v3/include/bits/istream.tcc	Mon Jan  3 00:19:08 2005
***************
*** 1,6 ****
  // istream classes -*- C++ -*-
  
! // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
  // Free Software Foundation, Inc.
  //
  // This file is part of the GNU ISO C++ Library.  This library is free
--- 1,6 ----
  // istream classes -*- C++ -*-
  
! // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
  // Free Software Foundation, Inc.
  //
  // This file is part of the GNU ISO C++ Library.  This library is free
*************** namespace std
*** 683,695 ****
              {
                const int_type __eof = traits_type::eof();
                __streambuf_type* __sb = this->rdbuf();
!               int_type __c = __eof;
  
-               if (__n != numeric_limits<streamsize>::max())
-                 --__n;
-               while (_M_gcount <= __n
-                      && !traits_type::eq_int_type(__c = __sb->sbumpc(), __eof))
- 		++_M_gcount;
  	      if (traits_type::eq_int_type(__c, __eof))
                  __err |= ios_base::eofbit;
              }
--- 683,705 ----
              {
                const int_type __eof = traits_type::eof();
                __streambuf_type* __sb = this->rdbuf();
!               int_type __c = __sb->sgetc();
! 
! 	      while (true)
! 		{
! 		  while (_M_gcount < __n
! 			 && !traits_type::eq_int_type(__c, __eof))
! 		    {
! 		      ++_M_gcount;
! 		      __c = __sb->snextc();
! 		    }
! 		  if (__n == numeric_limits<streamsize>::max()
! 		      && !traits_type::eq_int_type(__c, __eof))
! 		    _M_gcount = 0;
! 		  else
! 		    break;
! 		}
  
  	      if (traits_type::eq_int_type(__c, __eof))
                  __err |= ios_base::eofbit;
              }
*************** namespace std
*** 718,736 ****
              {
                const int_type __eof = traits_type::eof();
                __streambuf_type* __sb = this->rdbuf();
!               int_type __c = __eof;
  
-               if (__n != numeric_limits<streamsize>::max())
-                 --__n;
-               while (_M_gcount <= __n
-                      && !traits_type::eq_int_type(__c = __sb->sbumpc(), __eof))
-                 {
-                   ++_M_gcount;
-                   if (traits_type::eq_int_type(__c, __delim))
-                     break;
-                 }
                if (traits_type::eq_int_type(__c, __eof))
                  __err |= ios_base::eofbit;
              }
            catch(...)
              { this->_M_setstate(ios_base::badbit); }
--- 728,759 ----
              {
                const int_type __eof = traits_type::eof();
                __streambuf_type* __sb = this->rdbuf();
!               int_type __c = __sb->sgetc();
! 
! 	      while (true)
! 		{
! 		  while (_M_gcount < __n
! 			 && !traits_type::eq_int_type(__c, __eof)
! 			 && !traits_type::eq_int_type(__c, __delim))
! 		    {
! 		      ++_M_gcount;
! 		      __c = __sb->snextc();
! 		    }
! 		  if (__n == numeric_limits<streamsize>::max()
! 		      && !traits_type::eq_int_type(__c, __eof)
! 		      && !traits_type::eq_int_type(__c, __delim))
! 		    _M_gcount = 0;
! 		  else
! 		    break;
! 		}
  
                if (traits_type::eq_int_type(__c, __eof))
                  __err |= ios_base::eofbit;
+ 	      else if (traits_type::eq_int_type(__c, __delim))
+ 		{
+ 		  ++_M_gcount;
+ 		  __sb->sbumpc();
+ 		}
              }
            catch(...)
              { this->_M_setstate(ios_base::badbit); }
diff -prN libstdc++-v3-orig/src/istream.cc libstdc++-v3/src/istream.cc
*** libstdc++-v3-orig/src/istream.cc	Fri Nov 26 21:34:23 2004
--- libstdc++-v3/src/istream.cc	Mon Jan  3 00:38:32 2005
***************
*** 1,6 ****
  // Input streams -*- C++ -*-
  
! // Copyright (C) 2004 Free Software Foundation, Inc.
  //
  // This file is part of the GNU ISO C++ Library.  This library is free
  // software; you can redistribute it and/or modify it under the
--- 1,6 ----
  // Input streams -*- C++ -*-
  
! // Copyright (C) 2004, 2005 Free Software Foundation, Inc.
  //
  // This file is part of the GNU ISO C++ Library.  This library is free
  // software; you can redistribute it and/or modify it under the
*************** namespace std
*** 124,151 ****
  	      __streambuf_type* __sb = this->rdbuf();
  	      int_type __c = __sb->sgetc();
  	      
! 	      const bool __bound = __n != numeric_limits<streamsize>::max();
! 	      if (__bound)
! 		--__n;
! 	      while (_M_gcount <= __n
! 		     && !traits_type::eq_int_type(__c, __eof))
! 		{
! 		  streamsize __size = __sb->egptr() - __sb->gptr();
! 		  if (__bound)
! 		    __size = std::min(__size, streamsize(__n - _M_gcount + 1));
! 
! 		  if (__size > 1)
  		    {
! 		      __sb->gbump(__size);
! 		      _M_gcount += __size;
! 		      __c = __sb->sgetc();
  		    }
  		  else
! 		    {
! 		      ++_M_gcount;
! 		      __c = __sb->snextc();
! 		    }		  
  		}
  	      if (traits_type::eq_int_type(__c, __eof))
  		__err |= ios_base::eofbit;
  	    }
--- 124,156 ----
  	      __streambuf_type* __sb = this->rdbuf();
  	      int_type __c = __sb->sgetc();
  	      
! 	      while (true)
! 		{
! 		  while (_M_gcount < __n
! 			 && !traits_type::eq_int_type(__c, __eof))
  		    {
! 		      streamsize __size = std::min(streamsize(__sb->egptr()
! 							      - __sb->gptr()),
! 						   streamsize(__n - _M_gcount));
! 		      if (__size > 1)
! 			{
! 			  __sb->gbump(__size);
! 			  _M_gcount += __size;
! 			  __c = __sb->sgetc();
! 			}
! 		      else
! 			{
! 			  ++_M_gcount;
! 			  __c = __sb->snextc();
! 			} 
  		    }
+ 		  if (__n == numeric_limits<streamsize>::max()
+ 		      && !traits_type::eq_int_type(__c, __eof))
+ 		    _M_gcount == 0;
  		  else
! 		    break;
  		}
+ 
  	      if (traits_type::eq_int_type(__c, __eof))
  		__err |= ios_base::eofbit;
  	    }
*************** namespace std
*** 177,210 ****
  	      __streambuf_type* __sb = this->rdbuf();
  	      int_type __c = __sb->sgetc();
  
! 	      const bool __bound = __n != numeric_limits<streamsize>::max();
! 	      if (__bound)
! 		--__n;
! 	      while (_M_gcount <= __n
! 		     && !traits_type::eq_int_type(__c, __eof)
! 		     && !traits_type::eq_int_type(__c, __delim))
  		{
! 		  streamsize __size = __sb->egptr() - __sb->gptr();
! 		  if (__bound)
! 		    __size = std::min(__size, streamsize(__n - _M_gcount + 1));
! 
! 		  if (__size > 1)
! 		    {
! 		      const char_type* __p = traits_type::find(__sb->gptr(),
! 							       __size,
! 							       __cdelim);
! 		      if (__p)
! 			__size = __p - __sb->gptr();
! 		      __sb->gbump(__size);
! 		      _M_gcount += __size;
! 		      __c = __sb->sgetc();
  		    }
  		  else
! 		    {
! 		      ++_M_gcount;
! 		      __c = __sb->snextc();
! 		    }		  
  		}
  	      if (traits_type::eq_int_type(__c, __eof))
  		__err |= ios_base::eofbit;
  	      else if (traits_type::eq_int_type(__c, __delim))
--- 182,221 ----
  	      __streambuf_type* __sb = this->rdbuf();
  	      int_type __c = __sb->sgetc();
  
! 	      while (true)
  		{
! 		  while (_M_gcount < __n
! 			 && !traits_type::eq_int_type(__c, __eof)
! 			 && !traits_type::eq_int_type(__c, __delim))
! 		    {
! 		      streamsize __size = std::min(streamsize(__sb->egptr()
! 							      - __sb->gptr()),
! 						   streamsize(__n - _M_gcount));
! 		      if (__size > 1)
! 			{
! 			  const char_type* __p = traits_type::find(__sb->gptr(),
! 								   __size,
! 								   __cdelim);
! 			  if (__p)
! 			    __size = __p - __sb->gptr();
! 			  __sb->gbump(__size);
! 			  _M_gcount += __size;
! 			  __c = __sb->sgetc();
! 			}
! 		      else
! 			{
! 			  ++_M_gcount;
! 			  __c = __sb->snextc();
! 			}
  		    }
+ 		  if (__n == numeric_limits<streamsize>::max()
+ 		      && !traits_type::eq_int_type(__c, __eof)
+ 		      && !traits_type::eq_int_type(__c, __delim))
+ 		    _M_gcount = 0;
  		  else
! 		    break;
  		}
+ 
  	      if (traits_type::eq_int_type(__c, __eof))
  		__err |= ios_base::eofbit;
  	      else if (traits_type::eq_int_type(__c, __delim))
*************** namespace std
*** 390,418 ****
  	      const int_type __eof = traits_type::eof();
  	      __streambuf_type* __sb = this->rdbuf();
  	      int_type __c = __sb->sgetc();
- 	      
- 	      const bool __bound = __n != numeric_limits<streamsize>::max();
- 	      if (__bound)
- 		--__n;
- 	      while (_M_gcount <= __n
- 		     && !traits_type::eq_int_type(__c, __eof))
- 		{
- 		  streamsize __size = __sb->egptr() - __sb->gptr();
- 		  if (__bound)
- 		    __size = std::min(__size, streamsize(__n - _M_gcount + 1));
  
! 		  if (__size > 1)
  		    {
! 		      __sb->gbump(__size);
! 		      _M_gcount += __size;
! 		      __c = __sb->sgetc();
  		    }
  		  else
! 		    {
! 		      ++_M_gcount;
! 		      __c = __sb->snextc();
! 		    }		  
  		}
  	      if (traits_type::eq_int_type(__c, __eof))
  		__err |= ios_base::eofbit;
  	    }
--- 401,434 ----
  	      const int_type __eof = traits_type::eof();
  	      __streambuf_type* __sb = this->rdbuf();
  	      int_type __c = __sb->sgetc();
  
! 	      while (true)
! 		{
! 		  while (_M_gcount < __n
! 			 && !traits_type::eq_int_type(__c, __eof))
  		    {
! 		      streamsize __size = std::min(streamsize(__sb->egptr()
! 							      - __sb->gptr()),
! 						   streamsize(__n - _M_gcount));
! 		      if (__size > 1)
! 			{
! 			  __sb->gbump(__size);
! 			  _M_gcount += __size;
! 			  __c = __sb->sgetc();
! 			}
! 		      else
! 			{
! 			  ++_M_gcount;
! 			  __c = __sb->snextc();
! 			}
  		    }
+ 		  if (__n == numeric_limits<streamsize>::max()
+ 		      && !traits_type::eq_int_type(__c, __eof))
+ 		    _M_gcount == 0;
  		  else
! 		    break;
  		}
+ 
  	      if (traits_type::eq_int_type(__c, __eof))
  		__err |= ios_base::eofbit;
  	    }
*************** namespace std
*** 444,477 ****
  	      __streambuf_type* __sb = this->rdbuf();
  	      int_type __c = __sb->sgetc();
  
! 	      const bool __bound = __n != numeric_limits<streamsize>::max();
! 	      if (__bound)
! 		--__n;
! 	      while (_M_gcount <= __n
! 		     && !traits_type::eq_int_type(__c, __eof)
! 		     && !traits_type::eq_int_type(__c, __delim))
  		{
! 		  streamsize __size = __sb->egptr() - __sb->gptr();
! 		  if (__bound)
! 		    __size = std::min(__size, streamsize(__n - _M_gcount + 1));
! 
! 		  if (__size > 1)
! 		    {
! 		      const char_type* __p = traits_type::find(__sb->gptr(),
! 							       __size,
! 							       __cdelim);
! 		      if (__p)
! 			__size = __p - __sb->gptr();
! 		      __sb->gbump(__size);
! 		      _M_gcount += __size;
! 		      __c = __sb->sgetc();
  		    }
  		  else
! 		    {
! 		      ++_M_gcount;
! 		      __c = __sb->snextc();
! 		    }		  
  		}
  	      if (traits_type::eq_int_type(__c, __eof))
  		__err |= ios_base::eofbit;
  	      else if (traits_type::eq_int_type(__c, __delim))
--- 460,499 ----
  	      __streambuf_type* __sb = this->rdbuf();
  	      int_type __c = __sb->sgetc();
  
! 	      while (true)
  		{
! 		  while (_M_gcount < __n
! 			 && !traits_type::eq_int_type(__c, __eof)
! 			 && !traits_type::eq_int_type(__c, __delim))
! 		    {
! 		      streamsize __size = std::min(streamsize(__sb->egptr()
! 							      - __sb->gptr()),
! 						   streamsize(__n - _M_gcount));
! 		      if (__size > 1)
! 			{
! 			  const char_type* __p = traits_type::find(__sb->gptr(),
! 								   __size,
! 								   __cdelim);
! 			  if (__p)
! 			    __size = __p - __sb->gptr();
! 			  __sb->gbump(__size);
! 			  _M_gcount += __size;
! 			  __c = __sb->sgetc();
! 			}
! 		      else
! 			{
! 			  ++_M_gcount;
! 			  __c = __sb->snextc();
! 			}
  		    }
+ 		  if (__n == numeric_limits<streamsize>::max()
+ 		      && !traits_type::eq_int_type(__c, __eof)
+ 		      && !traits_type::eq_int_type(__c, __delim))
+ 		    _M_gcount = 0;
  		  else
! 		    break;
  		}
+ 
  	      if (traits_type::eq_int_type(__c, __eof))
  		__err |= ios_base::eofbit;
  	      else if (traits_type::eq_int_type(__c, __delim))

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]