Handle invalid glibc FILE buffer

This commit is contained in:
Victor Zverovich 2025-07-06 08:58:22 -07:00
parent 513f978241
commit 300ce75ca6
2 changed files with 16 additions and 1 deletions

View File

@ -1549,7 +1549,8 @@ template <typename F> class glibc_file : public file_base<F> {
bool needs_flush() const {
if ((this->file_->_flags & line_buffered) == 0) return false;
char* end = this->file_->_IO_write_end;
return memchr(end, '\n', to_unsigned(this->file_->_IO_write_ptr - end));
auto size = max_of<ptrdiff_t>(this->file_->_IO_write_ptr - end, 0);
return memchr(end, '\n', static_cast<size_t>(size));
}
void flush() { fflush_unlocked(this->file_); }

View File

@ -2549,6 +2549,20 @@ TEST(format_test, writer) {
EXPECT_EQ(s.str(), "foo");
}
#if FMT_USE_FCNTL && !defined(_WIN32)
TEST(format_test, invalid_glibc_buffer) {
auto pipe = fmt::pipe();
auto write_end = pipe.write_end.fdopen("w");
auto file = write_end.get();
// This results in _IO_write_ptr < _IO_write_end.
fprintf(file, "111\n");
setvbuf(file, nullptr, _IOLBF, 0);
fmt::print(file, "------\n");
}
#endif // FMT_USE_FCNTL
#if FMT_USE_BITINT
FMT_PRAGMA_CLANG(diagnostic ignored "-Wbit-int-extension")