diff options
author | Paolo Carlini <paolo.carlini@oracle.com> | 2011-02-28 23:50:57 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2011-02-28 23:50:57 +0000 |
commit | 1139a7354d6818da06edf5227ef6c12c08289b91 (patch) | |
tree | ee95f0e866d1d1bafe977f8e5861e6f678607891 /libstdc++-v3/include | |
parent | 6dfef9cca7628d454ed535736f9d063a7d45911d (diff) | |
download | gcc-1139a7354d6818da06edf5227ef6c12c08289b91.zip gcc-1139a7354d6818da06edf5227ef6c12c08289b91.tar.gz gcc-1139a7354d6818da06edf5227ef6c12c08289b91.tar.bz2 |
re PR libstdc++/47921 (pbump will overflow when input n is larger than 2G-1)
2011-02-28 Paolo Carlini <paolo.carlini@oracle.com>
PR libstdc++/47921
* include/std/streambuf (basic_streambuf<>::__safe_gbump,
__safe_pbump): Add.
* include/bits/streambuf.tcc (basic_streambuf<>::xgetn,
xputn): Use the latter.
* include/bits/streambuf_iterator.h: Likewise.
* src/strstream.cc: Likewise.
* src/streambuf.cc: Likewise.
* src/compatibility.cc: Likewise.
* src/istream.cc: Likewise.
* include/bits/fstream.tcc (basic_filebuf<>::xsgetn): Use setg
instead of gbump.
* include/std/sstream (basic_stringbuf<>::_M_pbump): Add.
* include/bits/sstream.tcc (basic_stringbuf<>::seekoff,
seekpos, _M_sync): Use setg, setp, and _M_pbump.
* config/abi/pre/gnu.ver: Tweak.
From-SVN: r170579
Diffstat (limited to 'libstdc++-v3/include')
-rw-r--r-- | libstdc++-v3/include/bits/fstream.tcc | 12 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/sstream.tcc | 29 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/streambuf.tcc | 6 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/streambuf_iterator.h | 6 | ||||
-rw-r--r-- | libstdc++-v3/include/std/sstream | 5 | ||||
-rw-r--r-- | libstdc++-v3/include/std/streambuf | 7 |
6 files changed, 45 insertions, 20 deletions
diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc index edaff97..282934e 100644 --- a/libstdc++-v3/include/bits/fstream.tcc +++ b/libstdc++-v3/include/bits/fstream.tcc @@ -584,14 +584,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const streamsize __avail = this->egptr() - this->gptr(); if (__avail != 0) { - if (__avail == 1) - *__s = *this->gptr(); - else - traits_type::copy(__s, this->gptr(), __avail); + traits_type::copy(__s, this->gptr(), __avail); __s += __avail; - this->gbump(__avail); - __ret += __avail; - __n -= __avail; + this->setg(this->eback(), this->gptr() + __avail, + this->egptr()); + __ret += __avail; + __n -= __avail; } // Need to loop in case of short reads (relatively common diff --git a/libstdc++-v3/include/bits/sstream.tcc b/libstdc++-v3/include/bits/sstream.tcc index 8956e9e..ffa92e7 100644 --- a/libstdc++-v3/include/bits/sstream.tcc +++ b/libstdc++-v3/include/bits/sstream.tcc @@ -1,7 +1,7 @@ // String based streams -*- C++ -*- // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, -// 2006, 2007, 2009, 2010 +// 2006, 2007, 2008, 2009, 2010, 2011 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -178,14 +178,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION && __newoffi >= 0 && this->egptr() - __beg >= __newoffi) { - this->gbump((__beg + __newoffi) - this->gptr()); + this->setg(this->eback(), this->eback() + __newoffi, + this->egptr()); __ret = pos_type(__newoffi); } if ((__testout || __testboth) && __newoffo >= 0 && this->egptr() - __beg >= __newoffo) { - this->pbump((__beg + __newoffo) - this->pptr()); + _M_pbump(this->pbase(), this->epptr(), __newoffo); __ret = pos_type(__newoffo); } } @@ -212,9 +213,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__testpos) { if (__testin) - this->gbump((__beg + __pos) - this->gptr()); + this->setg(this->eback(), this->eback() + __pos, + this->egptr()); if (__testout) - this->pbump((__beg + __pos) - this->pptr()); + _M_pbump(this->pbase(), this->epptr(), __pos); __ret = __sp; } } @@ -243,8 +245,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION this->setg(__base, __base + __i, __endg); if (__testout) { - this->setp(__base, __endp); - this->pbump(__o); + _M_pbump(__base, __endp, __o); // egptr() always tracks the string end. When !__testin, // for the correct functioning of the streambuf inlines // the other get area pointers are identical. @@ -253,6 +254,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } + template <class _CharT, class _Traits, class _Alloc> + void + basic_stringbuf<_CharT, _Traits, _Alloc>:: + _M_pbump(char_type* __pbeg, char_type* __pend, off_type __off) + { + this->setp(__pbeg, __pend); + while (__off > __gnu_cxx::__numeric_traits<int>::__max) + { + this->pbump(__gnu_cxx::__numeric_traits<int>::__max); + __off -= __gnu_cxx::__numeric_traits<int>::__max; + } + this->pbump(__off); + } + // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. // NB: This syntax is a GNU extension. diff --git a/libstdc++-v3/include/bits/streambuf.tcc b/libstdc++-v3/include/bits/streambuf.tcc index 253f308..d154ef1 100644 --- a/libstdc++-v3/include/bits/streambuf.tcc +++ b/libstdc++-v3/include/bits/streambuf.tcc @@ -1,7 +1,7 @@ // Stream buffer classes -*- C++ -*- // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, -// 2006, 2009, 2010 Free Software Foundation, Inc. +// 2006, 2007, 2008, 2009, 2010, 2011 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 @@ -57,7 +57,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION traits_type::copy(__s, this->gptr(), __len); __ret += __len; __s += __len; - this->gbump(__len); + this->__safe_gbump(__len); } if (__ret < __n) @@ -91,7 +91,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION traits_type::copy(this->pptr(), __s, __len); __ret += __len; __s += __len; - this->pbump(__len); + this->__safe_pbump(__len); } if (__ret < __n) diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h b/libstdc++-v3/include/bits/streambuf_iterator.h index 6032a29..83ae678 100644 --- a/libstdc++-v3/include/bits/streambuf_iterator.h +++ b/libstdc++-v3/include/bits/streambuf_iterator.h @@ -1,7 +1,7 @@ // Streambuf iterators // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, -// 2006, 2007, 2009, 2010 +// 2006, 2007, 2009, 2010, 2011 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -339,7 +339,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__n > 1) { traits_type::copy(__result, __sb->gptr(), __n); - __sb->gbump(__n); + __sb->__safe_gbump(__n); __result += __n; __c = __sb->underflow(); } @@ -379,7 +379,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __n, __val); if (__p) __n = __p - __sb->gptr(); - __sb->gbump(__n); + __sb->__safe_gbump(__n); __c = __sb->sgetc(); } else diff --git a/libstdc++-v3/include/std/sstream b/libstdc++-v3/include/std/sstream index 6dd0a3d..bf2862a 100644 --- a/libstdc++-v3/include/std/sstream +++ b/libstdc++-v3/include/std/sstream @@ -241,6 +241,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION this->setg(this->pptr(), this->pptr(), this->pptr()); } } + + // Works around the issue with pbump, part of the protected + // interface of basic_streambuf, taking just an int. + void + _M_pbump(char_type* __pbeg, char_type* __pend, off_type __off); }; diff --git a/libstdc++-v3/include/std/streambuf b/libstdc++-v3/include/std/streambuf index 0121ac2..b46efec 100644 --- a/libstdc++-v3/include/std/streambuf +++ b/libstdc++-v3/include/std/streambuf @@ -769,6 +769,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } #endif + // Also used by specializations for char and wchar_t in src. + void + __safe_gbump(streamsize __n) { _M_in_cur += __n; } + + void + __safe_pbump(streamsize __n) { _M_out_cur += __n; } + private: // _GLIBCXX_RESOLVE_LIB_DEFECTS // Side effect of DR 50. |