Skip to content

Commit ef55545

Browse files
committed
Add overflow test for fprintf
1 parent 1dd65af commit ef55545

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

libc/test/src/stdio/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ if(LLVM_LIBC_FULL_BUILD)
169169
libc.src.stdio.ferror
170170
libc.src.stdio.fopen
171171
libc.src.stdio.fread
172+
libc.src.stdio.fopencookie
172173
)
173174
# This is to be used for tests which write to libc's platform streams
174175
# under full build but write to system-lib's streams otherwise.

libc/test/src/stdio/fprintf_test.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,29 @@
1010
#include "src/stdio/fclose.h"
1111
#include "src/stdio/ferror.h"
1212
#include "src/stdio/fopen.h"
13+
#include "src/stdio/fopencookie.h"
1314
#include "src/stdio/fread.h"
1415
#endif // LIBC_COPT_STDIO_USE_SYSTEM_FILE
1516

1617
#include "src/stdio/fprintf.h"
1718

18-
#include "test/UnitTest/Test.h"
19+
#include "src/__support/CPP/limits.h"
1920
#include "test/UnitTest/ErrnoCheckingTest.h"
2021
#include "test/UnitTest/ErrnoSetterMatcher.h"
22+
#include "test/UnitTest/Test.h"
2123

2224
namespace printf_test {
2325
#ifndef LIBC_COPT_STDIO_USE_SYSTEM_FILE
2426
using LIBC_NAMESPACE::fclose;
2527
using LIBC_NAMESPACE::ferror;
2628
using LIBC_NAMESPACE::fopen;
29+
using LIBC_NAMESPACE::fopencookie;
2730
using LIBC_NAMESPACE::fread;
2831
#else // defined(LIBC_COPT_STDIO_USE_SYSTEM_FILE)
2932
using ::fclose;
3033
using ::ferror;
3134
using ::fopen;
35+
using ::fopencookie;
3236
using ::fread;
3337
#endif // LIBC_COPT_STDIO_USE_SYSTEM_FILE
3438
} // namespace printf_test
@@ -86,3 +90,25 @@ TEST(LlvmLibcFPrintfTest, WriteToFile) {
8690

8791
ASSERT_EQ(printf_test::fclose(file), 0);
8892
}
93+
94+
struct NoopStream {};
95+
96+
static ssize_t noop_write(void *, const char *, size_t size) { return size; }
97+
98+
TEST(LlvmLibcFPrintfTest, CharsWrittenOverflow) {
99+
NoopStream stream;
100+
cookie_io_functions_t funcs = {nullptr, &noop_write, nullptr, nullptr};
101+
::FILE *file = printf_test::fopencookie(&stream, "w", funcs);
102+
ASSERT_NE(file, nullptr);
103+
104+
// Trigger an overflow in the return value of fprintf by writing more than
105+
// INT_MAX bytes. We do this by printing a string with precision INT_MAX, and
106+
// then one more character.
107+
int max_int = LIBC_NAMESPACE::cpp::numeric_limits<int>::max();
108+
int result = LIBC_NAMESPACE::fprintf(file, "%*sA", max_int, "");
109+
110+
EXPECT_LT(result, 0);
111+
ASSERT_ERRNO_EQ(EOVERFLOW);
112+
113+
EXPECT_EQ(printf_test::fclose(file), 0);
114+
}

0 commit comments

Comments
 (0)