aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <pcarlini@suse.de>2005-01-03 00:02:47 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2005-01-03 00:02:47 +0000
commitbea53dbfbcfb1c28264244e151a6170be97fe378 (patch)
tree146256ff5e26b155136c80927e19e8b3c49a6faf
parent1330529e587cb17366dc5ae6fc510f32b19ad123 (diff)
downloadgcc-bea53dbfbcfb1c28264244e151a6170be97fe378.zip
gcc-bea53dbfbcfb1c28264244e151a6170be97fe378.tar.gz
gcc-bea53dbfbcfb1c28264244e151a6170be97fe378.tar.bz2
istream.cc (basic_istream<char>::ignore(streamsize), [...]): Avoid _M_gcount overflows.
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. From-SVN: r92816
-rw-r--r--libstdc++-v3/ChangeLog11
-rw-r--r--libstdc++-v3/include/bits/istream.tcc57
-rw-r--r--libstdc++-v3/src/istream.cc186
3 files changed, 155 insertions, 99 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 6a61a8e..8d25535 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 b363d52..49cdc80 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 39de753..a49878a 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))