https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118099
--- Comment #5 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Jonathan Wakely <[email protected]>: https://gcc.gnu.org/g:43e4d697586364decbad7f67a204189afef6e765 commit r17-5971-g43e4d697586364decbad7f67a204189afef6e765 Author: Jonathan Wakely <[email protected]> Date: Thu Oct 22 23:18:57 2026 +0100 libstdc++: Avoid possible null pointer arithmetic in basic_filebuf::overflow [PR118099] The unbuffered path in basic_filebuf::overflow calls _M_convert_to_external(&__conv, 1) to output a single character. But if a partial codecvt conversion happens in _M_convert_to_external then it calculates the number of unconverted characters in the filebuf's put area by calling pptr(). In the unbuffered case pptr() returns a null pointer and so the arithmetic on it is undefined. Although GCC doesn't diagnose this, Clang's UBSan does: .../include/c++/16/bits/fstream.tcc:655:19: runtime error: applying non-zero offset to non-null pointer 0x7ffd0d20eca7 produced null pointer _M_convert_to_external should only read from the buffer passed to it, not assume that the streambuf's put area exists or is equivalent to the buffer that was passed. This probably isn't a problem in real code, because the null pptr() in _M_convert_to_external was only reachable for a non-conforming codecvt facet that lies about max_length() or for some reason performs a partial conversion on a single character even when sufficient output space is available (as in the new testcases). But it is more robust to not access pptr() directly when we are called with a pointer to the sequence that should be converted. This also enables a further correctness fix to basic_filebuf::overflow in a subsequent commit. The retry code can be further simplified because not only is using pptr() unsafe, but we can just use [__iend, __ibuf + __ilen) as the input range, instead of [__iend, __iend + (pptr() - __iend)). That was just unnecessarily complicated. The retry_forcing_codecvt in the new test was generated by an LLM, although greatly simplified by me so that the bug is detected with a simple VERIFY rather than examining the characters output by the facet. Assisted-by: LLM libstdc++-v3/ChangeLog: PR libstdc++/118099 * include/bits/fstream.tcc (basic_filebuf::_M_convert_to_external): Use __ibuf + __ilen instead of this->pptr(). * testsuite/27_io/basic_filebuf/overflow/char/118099-unbuffered.cc: New test. * testsuite/27_io/basic_filebuf/overflow/wchar_t/118099-unbuffered.cc: New test. Reviewed-by: Tomasz KamiÅski <[email protected]>
