diff options
author | Marshall Clow <mclow.lists@gmail.com> | 2017-09-12 15:00:43 +0000 |
---|---|---|
committer | Marshall Clow <mclow.lists@gmail.com> | 2017-09-12 15:00:43 +0000 |
commit | 29149d3e3565813dcf8b9adc895a6a39eeccdd09 (patch) | |
tree | 69559651ab6f3567b5404f1dfcf63a9b467b79f9 | |
parent | 60f8ad1b1dbfa6673919bbf3e7e629997224651d (diff) |
Make pbump (internally) handle sizes bigger than MAX_INT. Fixes PR#33725 - thanks to Jonathan Wakely for the report
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@313031 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/fstream | 8 | ||||
-rw-r--r-- | include/locale | 2 | ||||
-rw-r--r-- | include/sstream | 20 | ||||
-rw-r--r-- | include/streambuf | 3 | ||||
-rw-r--r-- | src/strstream.cpp | 6 | ||||
-rw-r--r-- | test/std/input.output/stream.buffers/streambuf/streambuf.protected/streambuf.put.area/pbump2gig.pass.cpp | 41 |
6 files changed, 66 insertions, 14 deletions
diff --git a/include/fstream b/include/fstream index ffd569839..f57908c8d 100644 --- a/include/fstream +++ b/include/fstream @@ -315,7 +315,7 @@ basic_filebuf<_CharT, _Traits>::basic_filebuf(basic_filebuf&& __rhs) else this->setp((char_type*)__extbuf_, (char_type*)__extbuf_ + (__rhs. epptr() - __rhs.pbase())); - this->pbump(__rhs. pptr() - __rhs.pbase()); + this->__pbump(__rhs. pptr() - __rhs.pbase()); } else if (__rhs.eback()) { @@ -434,7 +434,7 @@ basic_filebuf<_CharT, _Traits>::swap(basic_filebuf& __rhs) ptrdiff_t __e = this->epptr() - this->pbase(); this->setp((char_type*)__extbuf_min_, (char_type*)__extbuf_min_ + __e); - this->pbump(__n); + this->__pbump(__n); } if (__rhs.eback() == (char_type*)__extbuf_min_) { @@ -450,7 +450,7 @@ basic_filebuf<_CharT, _Traits>::swap(basic_filebuf& __rhs) ptrdiff_t __e = __rhs.epptr() - __rhs.pbase(); __rhs.setp((char_type*)__rhs.__extbuf_min_, (char_type*)__rhs.__extbuf_min_ + __e); - __rhs.pbump(__n); + __rhs.__pbump(__n); } } @@ -724,7 +724,7 @@ basic_filebuf<_CharT, _Traits>::overflow(int_type __c) if (__r == codecvt_base::partial) { this->setp(const_cast<char_type*>(__e), this->pptr()); - this->pbump(this->epptr() - this->pbase()); + this->__pbump(this->epptr() - this->pbase()); } } else diff --git a/include/locale b/include/locale index d30d950c7..a86645d2c 100644 --- a/include/locale +++ b/include/locale @@ -4110,7 +4110,7 @@ wbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c) if (__r == codecvt_base::partial) { this->setp(const_cast<char_type *>(__e), this->pptr()); - this->pbump(this->epptr() - this->pbase()); + this->__pbump(this->epptr() - this->pbase()); } } else diff --git a/include/sstream b/include/sstream index fe65fd7db..31cb37a1e 100644 --- a/include/sstream +++ b/include/sstream @@ -289,7 +289,7 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::basic_stringbuf(basic_stringbuf&& if (__bout != -1) { this->setp(__p + __bout, __p + __eout); - this->pbump(__nout); + this->__pbump(__nout); } __hm_ = __hm == -1 ? nullptr : __p + __hm; __p = const_cast<char_type*>(__rhs.__str_.data()); @@ -332,7 +332,7 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::operator=(basic_stringbuf&& __rhs) if (__bout != -1) { this->setp(__p + __bout, __p + __eout); - this->pbump(__nout); + this->__pbump(__nout); } else this->setp(nullptr, nullptr); @@ -403,7 +403,7 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::swap(basic_stringbuf& __rhs) if (__rbout != -1) { this->setp(__p + __rbout, __p + __reout); - this->pbump(__rnout); + this->__pbump(__rnout); } else this->setp(nullptr, nullptr); @@ -416,7 +416,7 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::swap(basic_stringbuf& __rhs) if (__lbout != -1) { __rhs.setp(__p + __lbout, __p + __leout); - __rhs.pbump(__lnout); + __rhs.__pbump(__lnout); } else __rhs.setp(nullptr, nullptr); @@ -471,7 +471,15 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::str(const string_type& __s) this->setp(const_cast<char_type*>(__str_.data()), const_cast<char_type*>(__str_.data()) + __str_.size()); if (__mode_ & (ios_base::app | ios_base::ate)) - this->pbump(__sz); + { + while (__sz > INT_MAX) + { + this->pbump(INT_MAX); + __sz -= INT_MAX; + } + if (__sz > 0) + this->pbump(__sz); + } } } @@ -536,7 +544,7 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::overflow(int_type __c) __str_.resize(__str_.capacity()); char_type* __p = const_cast<char_type*>(__str_.data()); this->setp(__p, __p + __str_.size()); - this->pbump(__nout); + this->__pbump(__nout); __hm_ = this->pbase() + __hm; #ifndef _LIBCPP_NO_EXCEPTIONS } diff --git a/include/streambuf b/include/streambuf index f6182d64f..ea64f5780 100644 --- a/include/streambuf +++ b/include/streambuf @@ -255,6 +255,9 @@ protected: inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY void pbump(int __n) { __nout_ += __n; } + _LIBCPP_ALWAYS_INLINE + void __pbump(streamsize __n) { __nout_ += __n; } + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY void setp(char_type* __pbeg, char_type* __pend) { __bout_ = __nout_ = __pbeg; diff --git a/src/strstream.cpp b/src/strstream.cpp index 01523cf45..8b8521f76 100644 --- a/src/strstream.cpp +++ b/src/strstream.cpp @@ -186,7 +186,7 @@ strstreambuf::overflow(int_type __c) } setg(buf, buf + ninp, buf + einp); setp(buf + einp, buf + new_size); - pbump(static_cast<int>(nout)); + __pbump(nout); __strmode_ |= __allocated; } *pptr() = static_cast<char>(__c); @@ -282,7 +282,7 @@ strstreambuf::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmod // min(pbase, newpos), newpos, epptr() __off = epptr() - newpos; setp(min(pbase(), newpos), epptr()); - pbump(static_cast<int>((epptr() - pbase()) - __off)); + __pbump((epptr() - pbase()) - __off); } __p = newoff; } @@ -312,7 +312,7 @@ strstreambuf::seekpos(pos_type __sp, ios_base::openmode __which) // min(pbase, newpos), newpos, epptr() off_type temp = epptr() - newpos; setp(min(pbase(), newpos), epptr()); - pbump(static_cast<int>((epptr() - pbase()) - temp)); + __pbump((epptr() - pbase()) - temp); } __p = newoff; } diff --git a/test/std/input.output/stream.buffers/streambuf/streambuf.protected/streambuf.put.area/pbump2gig.pass.cpp b/test/std/input.output/stream.buffers/streambuf/streambuf.protected/streambuf.put.area/pbump2gig.pass.cpp new file mode 100644 index 000000000..a581f881d --- /dev/null +++ b/test/std/input.output/stream.buffers/streambuf/streambuf.protected/streambuf.put.area/pbump2gig.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <streambuf> + +// template <class charT, class traits = char_traits<charT> > +// class basic_streambuf; + +// void pbump(int n); + +#include <sstream> +#include <cassert> +#include "test_macros.h" + +struct SB : std::stringbuf +{ + SB() : std::stringbuf(std::ios::ate|std::ios::out) { } + const char* pubpbase() const { return pbase(); } + const char* pubpptr() const { return pptr(); } +}; + +int main() +{ +#ifndef TEST_HAS_NO_EXCEPTIONS + try { +#endif + std::string str(2147483648, 'a'); + SB sb; + sb.str(str); + assert(sb.pubpbase() <= sb.pubpptr()); +#ifndef TEST_HAS_NO_EXCEPTIONS + } + catch (const std::bad_alloc &) {} +#endif +} |