From bea53dbfbcfb1c28264244e151a6170be97fe378 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Mon, 3 Jan 2005 00:02:47 +0000 Subject: [PATCH] istream.cc (basic_istream::ignore(streamsize), [...]): Avoid _M_gcount overflows. 2005-01-02 Paolo Carlini * src/istream.cc (basic_istream::ignore(streamsize), basic_istream::ignore(streamsize, int_type), basic_istream::ignore(streamsize), basic_istream::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 --- libstdc++-v3/ChangeLog | 11 ++ libstdc++-v3/include/bits/istream.tcc | 57 +++++--- libstdc++-v3/src/istream.cc | 186 ++++++++++++++------------ 3 files changed, 155 insertions(+), 99 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 6a61a8e310c..8d25535bb09 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,14 @@ +2005-01-02 Paolo Carlini + + * src/istream.cc (basic_istream::ignore(streamsize), + basic_istream::ignore(streamsize, int_type), + basic_istream::ignore(streamsize), + basic_istream::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 * 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 b363d52091d..49cdc8050a3 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::max() + && !traits_type::eq_int_type(__c, __eof)) + _M_gcount = 0; + else + break; + } - if (__n != numeric_limits::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::max() + && !traits_type::eq_int_type(__c, __eof) + && !traits_type::eq_int_type(__c, __delim)) + _M_gcount = 0; + else + break; + } - if (__n != numeric_limits::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 39de7538f0d..a49878a5da2 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::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::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::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::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::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::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::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::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))