diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 6a61a8e310c2ea68f1239af8b8f46ab8600f67e7..8d25535bb09d03bd686566456acc432d54a95f56 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,14 @@
+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.
+
 2005-01-02  Chris Jefferson  <chris@bubblescope.net>
 
 	* include/bits/stl_algobase.h (mismatch): Correct concept check.
diff --git a/libstdc++-v3/include/bits/istream.tcc b/libstdc++-v3/include/bits/istream.tcc
index b363d52091db363f300851aca9887b00df8959ae..49cdc8050a3294b9d97ef63ad6c9795f98519b1f 100644
--- a/libstdc++-v3/include/bits/istream.tcc
+++ b/libstdc++-v3/include/bits/istream.tcc
@@ -1,6 +1,6 @@
 // istream classes -*- C++ -*-
 
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+// 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
@@ -683,13 +683,23 @@ namespace std
             {
               const int_type __eof = traits_type::eof();
               __streambuf_type* __sb = this->rdbuf();
-              int_type __c = __eof;
+              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 (__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;
             }
@@ -718,19 +728,32 @@ namespace std
             {
               const int_type __eof = traits_type::eof();
               __streambuf_type* __sb = this->rdbuf();
-              int_type __c = __eof;
+              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 (__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;
+	      else if (traits_type::eq_int_type(__c, __delim))
+		{
+		  ++_M_gcount;
+		  __sb->sbumpc();
+		}
             }
           catch(...)
             { this->_M_setstate(ios_base::badbit); }
diff --git a/libstdc++-v3/src/istream.cc b/libstdc++-v3/src/istream.cc
index 39de7538f0d9eb2cec96e64e180057be44b95c2c..a49878a5da20004408fb26a66f511c23be5e83e4 100644
--- a/libstdc++-v3/src/istream.cc
+++ b/libstdc++-v3/src/istream.cc
@@ -1,6 +1,6 @@
 // Input streams -*- C++ -*-
 
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// 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
@@ -124,28 +124,33 @@ namespace std
 	      __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))
+	      while (true)
 		{
-		  streamsize __size = __sb->egptr() - __sb->gptr();
-		  if (__bound)
-		    __size = std::min(__size, streamsize(__n - _M_gcount + 1));
-
-		  if (__size > 1)
+		  while (_M_gcount < __n
+			 && !traits_type::eq_int_type(__c, __eof))
 		    {
-		      __sb->gbump(__size);
-		      _M_gcount += __size;
-		      __c = __sb->sgetc();
+		      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
-		    {
-		      ++_M_gcount;
-		      __c = __sb->snextc();
-		    }		  
+		    break;
 		}
+
 	      if (traits_type::eq_int_type(__c, __eof))
 		__err |= ios_base::eofbit;
 	    }
@@ -177,34 +182,40 @@ namespace std
 	      __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))
+	      while (true)
 		{
-		  streamsize __size = __sb->egptr() - __sb->gptr();
-		  if (__bound)
-		    __size = std::min(__size, streamsize(__n - _M_gcount + 1));
-
-		  if (__size > 1)
+		  while (_M_gcount < __n
+			 && !traits_type::eq_int_type(__c, __eof)
+			 && !traits_type::eq_int_type(__c, __delim))
 		    {
-		      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();
+		      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
-		    {
-		      ++_M_gcount;
-		      __c = __sb->snextc();
-		    }		  
+		    break;
 		}
+
 	      if (traits_type::eq_int_type(__c, __eof))
 		__err |= ios_base::eofbit;
 	      else if (traits_type::eq_int_type(__c, __delim))
@@ -390,29 +401,34 @@ namespace std
 	      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)
+	      while (true)
+		{
+		  while (_M_gcount < __n
+			 && !traits_type::eq_int_type(__c, __eof))
 		    {
-		      __sb->gbump(__size);
-		      _M_gcount += __size;
-		      __c = __sb->sgetc();
+		      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
-		    {
-		      ++_M_gcount;
-		      __c = __sb->snextc();
-		    }		  
+		    break;
 		}
+
 	      if (traits_type::eq_int_type(__c, __eof))
 		__err |= ios_base::eofbit;
 	    }
@@ -444,34 +460,40 @@ namespace std
 	      __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))
+	      while (true)
 		{
-		  streamsize __size = __sb->egptr() - __sb->gptr();
-		  if (__bound)
-		    __size = std::min(__size, streamsize(__n - _M_gcount + 1));
-
-		  if (__size > 1)
+		  while (_M_gcount < __n
+			 && !traits_type::eq_int_type(__c, __eof)
+			 && !traits_type::eq_int_type(__c, __delim))
 		    {
-		      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();
+		      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
-		    {
-		      ++_M_gcount;
-		      __c = __sb->snextc();
-		    }		  
+		    break;
 		}
+
 	      if (traits_type::eq_int_type(__c, __eof))
 		__err |= ios_base::eofbit;
 	      else if (traits_type::eq_int_type(__c, __delim))