mirror of
https://github.com/fmtlib/fmt.git
synced 2026-11-09 14:50:24 +08:00
fix heap overflow in fmt::ostream with buffer_size = 0 (#5011)
output_file(path, buffer_size = 0) allocated a zero-size buffer, but ostream::grow can only make room by flushing, so a zero capacity is never increased. push_back then writes past the allocation and leaves size() above capacity(), after which append computes capacity_ - size_ as SIZE_MAX and copies the rest of the output out of bounds. If the first write is an append instead, the count is clamped to 0 and print never returns. Allocate at least one byte so a zero buffer size behaves like 1.
This commit is contained in:
parent
73b747233e
commit
4daaa87b86
@ -383,7 +383,9 @@ void ostream::grow(buffer<char>& buf, size_t) {
|
||||
|
||||
ostream::ostream(cstring_view path, const detail::ostream_params& params)
|
||||
: buffer<char>(grow), file_(path, params.oflag) {
|
||||
set(new char[params.buffer_size], params.buffer_size);
|
||||
// grow() can only make room by flushing, so the buffer can't be empty.
|
||||
size_t size = max_of<size_t>(params.buffer_size, 1);
|
||||
set(new char[size], size);
|
||||
}
|
||||
|
||||
ostream::ostream(ostream&& other) noexcept
|
||||
|
||||
@ -295,6 +295,15 @@ TEST(ostream_test, buffer_size) {
|
||||
EXPECT_READ(in, "foo");
|
||||
}
|
||||
|
||||
TEST(ostream_test, zero_buffer_size) {
|
||||
auto test_file = uniq_file_name(__LINE__);
|
||||
fmt::ostream out = fmt::output_file(test_file, fmt::buffer_size = 0);
|
||||
out.print("{}{}", 'f', "oo");
|
||||
out.close();
|
||||
file in(test_file, file::RDONLY);
|
||||
EXPECT_READ(in, "foo");
|
||||
}
|
||||
|
||||
TEST(ostream_test, truncate) {
|
||||
auto test_file = uniq_file_name(__LINE__);
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user