diff --git a/libc/src/__support/File/file.cpp b/libc/src/__support/File/file.cpp --- a/libc/src/__support/File/file.cpp +++ b/libc/src/__support/File/file.cpp @@ -57,7 +57,7 @@ // If the remaining bytes from |data| can fit in the buffer, write // into it. Else, write it directly to the platform stream. size_t remaining = len - write_size; - if (remaining <= len) { + if (remaining <= bufsize) { // TODO: Replace the for loop below with a call to internal memcpy. for (size_t i = 0; i < remaining; ++i) bufref[i] = dataref[i]; diff --git a/libc/test/src/__support/File/file_test.cpp b/libc/test/src/__support/File/file_test.cpp --- a/libc/test/src/__support/File/file_test.cpp +++ b/libc/test/src/__support/File/file_test.cpp @@ -335,3 +335,33 @@ ASSERT_EQ(f->close(), 0); } + +TEST(LlvmLibcFileTest, SmallBuffer) { + const char WRITE_DATA[] = "small buffer"; + constexpr size_t WRITE_SIZE = sizeof(WRITE_DATA); + constexpr size_t FILE_BUFFER_SIZE = sizeof(WRITE_DATA) / 2 - 1; + char file_buffer[FILE_BUFFER_SIZE]; + StringFile *f = new_string_file(file_buffer, FILE_BUFFER_SIZE, 0, false, "w"); + + ASSERT_EQ(WRITE_SIZE, f->write(WRITE_DATA, WRITE_SIZE)); + // Since data much larger than the buffer is being written, all of it should + // be available in the file without a flush operation. + EXPECT_EQ(f->get_pos(), sizeof(WRITE_DATA)); + ASSERT_STREQ(f->get_str(), WRITE_DATA); + + ASSERT_EQ(f->close(), 0); +} + +TEST(LlvmLibcFileTest, ZeroLengthBuffer) { + const char WRITE_DATA[] = "small buffer"; + constexpr size_t WRITE_SIZE = sizeof(WRITE_DATA); + StringFile *f = new_string_file(nullptr, 0, 0, true, "w"); + + ASSERT_EQ(WRITE_SIZE, f->write(WRITE_DATA, WRITE_SIZE)); + // Since there is no buffer space, all of the written data should + // be available in the file without a flush operation. + EXPECT_EQ(f->get_pos(), sizeof(WRITE_DATA)); + ASSERT_STREQ(f->get_str(), WRITE_DATA); + + ASSERT_EQ(f->close(), 0); +}