diff options
| author | Paolo Carlini <pcarlini@suse.de> | 2005-01-03 00:02:47 +0000 |
|---|---|---|
| committer | Paolo Carlini <paolo@gcc.gnu.org> | 2005-01-03 00:02:47 +0000 |
| commit | bea53dbfbcfb1c28264244e151a6170be97fe378 (patch) | |
| tree | 146256ff5e26b155136c80927e19e8b3c49a6faf /libstdc++-v3/src | |
| parent | 1330529e587cb17366dc5ae6fc510f32b19ad123 (diff) | |
| download | gcc-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
Diffstat (limited to 'libstdc++-v3/src')
| -rw-r--r-- | libstdc++-v3/src/istream.cc | 186 |
1 files changed, 104 insertions, 82 deletions
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)) |
