This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug libstdc++/81395] New: basic_filebuf::overflow recurses and overflows stack
- From: "redi at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Tue, 11 Jul 2017 12:12:52 +0000
- Subject: [Bug libstdc++/81395] New: basic_filebuf::overflow recurses and overflows stack
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81395
Bug ID: 81395
Summary: basic_filebuf::overflow recurses and overflows stack
Product: gcc
Version: 8.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
Assignee: unassigned at gcc dot gnu.org
Reporter: redi at gcc dot gnu.org
Target Milestone: ---
This program goes into an infinite recursion in basic_filebuf::overflow:
#include <fstream>
#include <cstring>
using std::memset;
int main()
{
{
std::ofstream s("test.txt");
char data[BUFSIZ];
memset(data, 'A', sizeof(data));
s.write(data, sizeof(data));
}
std::fstream s("test.txt");
char buf[BUFSIZ];
memset(buf, 0, sizeof(buf));
s.read(buf, sizeof(buf));
#ifdef FIX
s.seekg(sizeof(buf));
#endif
s << 'B';
}
The standard requires the seek performed when FIX is defined, so we're allowed
to give unexpected results. Even so, it would be preferable to not crash when
that's missing.
The problem is that the write calls overflow which starts with:
if (__testout)
{
if (_M_reading)
{
_M_destroy_pback();
const int __gptr_off = _M_get_ext_pos(_M_state_last);
if (_M_seek(__gptr_off, ios_base::cur, _M_state_last)
== pos_type(off_type(-1)))
return __ret;
}
That call to _M_seek calls _M_terminate_output which starts with:
// Part one: update the output sequence.
bool __testvalid = true;
if (this->pbase() < this->pptr())
{
const int_type __tmp = this->overflow();
if (traits_type::eq_int_type(__tmp, traits_type::eof()))
__testvalid = false;
}
So we go back to overflow() and then recurse.