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.