Skip to content

Commit 4ccf1d4

Browse files
authored
Fix out-of-bounds read in vprintf with trailing '%' (#4742)
1 parent be98ea8 commit 4ccf1d4

File tree

2 files changed

+10
-2
lines changed

2 files changed

+10
-2
lines changed

include/fmt/printf.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,8 @@ void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
438438
}
439439
write(out, basic_string_view<Char>(start, to_unsigned(it - 1 - start)));
440440

441+
if (it == end) report_error("invalid format string");
442+
441443
auto specs = format_specs();
442444
specs.set_align(align::right);
443445

test/printf-test.cc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ auto test_sprintf(fmt::basic_string_view<wchar_t> format, const Args&... args)
4646

4747
TEST(printf_test, no_args) { EXPECT_EQ("test", test_sprintf("test")); }
4848

49+
TEST(printf_test, trailing_percent) {
50+
EXPECT_THROW_MSG(test_sprintf("%"), format_error, "invalid format string");
51+
EXPECT_THROW_MSG(test_sprintf("hello%"), format_error,
52+
"invalid format string");
53+
EXPECT_THROW_MSG(test_sprintf("%1$d%", 1, 2), format_error,
54+
"invalid format string");
55+
}
56+
4957
TEST(printf_test, escape) {
5058
EXPECT_EQ("%", test_sprintf("%%"));
5159
EXPECT_EQ("before %", test_sprintf("before %%"));
@@ -76,8 +84,6 @@ TEST(printf_test, number_is_too_big_in_arg_index) {
7684
}
7785

7886
TEST(printf_test, switch_arg_indexing) {
79-
EXPECT_THROW_MSG(test_sprintf("%1$d%", 1, 2), format_error,
80-
"cannot switch from manual to automatic argument indexing");
8187
EXPECT_THROW_MSG(test_sprintf(format("%1$d%{}d", big_num), 1, 2),
8288
format_error, "number is too big");
8389
EXPECT_THROW_MSG(test_sprintf("%1$d%d", 1, 2), format_error,

0 commit comments

Comments
 (0)