mirror of
https://github.com/fmtlib/fmt.git
synced 2026-04-30 19:09:22 +08:00
Don't assume nul termination in printf
Thanks ZUENS2020 for reporting.
This commit is contained in:
parent
ea85b81ccd
commit
dc05bee307
4
.github/workflows/linux.yml
vendored
4
.github/workflows/linux.yml
vendored
@ -48,6 +48,8 @@ jobs:
|
||||
- cxx: clang++-14
|
||||
build_type: Debug
|
||||
std: 20
|
||||
cxxflags: -fsanitize=address
|
||||
cxxflags_extra: -fno-sanitize-recover=all -fno-omit-frame-pointer
|
||||
- cxx: clang++-14
|
||||
build_type: Debug
|
||||
std: 20
|
||||
@ -154,7 +156,7 @@ jobs:
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
env:
|
||||
CXX: ${{matrix.cxx}}
|
||||
CXXFLAGS: ${{matrix.cxxflags}}
|
||||
CXXFLAGS: ${{matrix.cxxflags}} ${{matrix.cxxflags_extra}}
|
||||
run: |
|
||||
cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
|
||||
-DCMAKE_CXX_STANDARD=${{matrix.std}} \
|
||||
|
||||
@ -330,6 +330,7 @@ template <typename Char, typename GetArg>
|
||||
auto parse_header(const Char*& it, const Char* end, format_specs& specs,
|
||||
GetArg get_arg) -> int {
|
||||
int arg_index = -1;
|
||||
if (it == end) return arg_index;
|
||||
Char c = *it;
|
||||
if (c >= '0' && c <= '9') {
|
||||
// Parse an argument index (if followed by '$') or a width possibly
|
||||
|
||||
@ -268,22 +268,6 @@ TEST(util_test, format_system_error) {
|
||||
fmt::format_system_error(message, EDOM, "test");
|
||||
auto ec = std::error_code(EDOM, std::generic_category());
|
||||
EXPECT_EQ(to_string(message), std::system_error(ec, "test").what());
|
||||
message = fmt::memory_buffer();
|
||||
|
||||
// Check if std::allocator throws on allocating max size_t / 2 chars.
|
||||
size_t max_size = max_value<size_t>() / 2;
|
||||
bool throws_on_alloc = false;
|
||||
try {
|
||||
auto alloc = std::allocator<char>();
|
||||
alloc.deallocate(alloc.allocate(max_size), max_size);
|
||||
} catch (const std::bad_alloc&) {
|
||||
throws_on_alloc = true;
|
||||
}
|
||||
if (!throws_on_alloc) {
|
||||
fmt::print(stderr, "warning: std::allocator allocates {} chars\n",
|
||||
max_size);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(util_test, system_error) {
|
||||
|
||||
@ -313,7 +313,8 @@ TEST(printf_test, positional_precision) {
|
||||
EXPECT_EQ("Hell", test_sprintf("%2$.*1$s", 4, "Hello"));
|
||||
EXPECT_THROW_MSG(test_sprintf("%2$.*1$d", 5.0, 42), format_error,
|
||||
"precision is not integer");
|
||||
EXPECT_THROW_MSG(test_sprintf("%2$.*1$d"), format_error, "argument not found");
|
||||
EXPECT_THROW_MSG(test_sprintf("%2$.*1$d"), format_error,
|
||||
"argument not found");
|
||||
EXPECT_THROW_MSG(test_sprintf("%2$.*1$d", big_num, 42), format_error,
|
||||
"number is too big");
|
||||
}
|
||||
@ -322,7 +323,8 @@ TEST(printf_test, positional_width_and_precision) {
|
||||
EXPECT_EQ(" 00042", test_sprintf("%3$*1$.*2$d", 7, 5, 42));
|
||||
EXPECT_EQ(" ab", test_sprintf("%3$*1$.*2$s", 7, 2, "abcdef"));
|
||||
EXPECT_EQ(" 00042", test_sprintf("%3$*1$.*2$x", 7, 5, 0x42));
|
||||
EXPECT_EQ("100.4400000", test_sprintf("%6$-*5$.*4$f%3$s%2$s%1$s", "", "", "", 7, 4, 100.44));
|
||||
EXPECT_EQ("100.4400000",
|
||||
test_sprintf("%6$-*5$.*4$f%3$s%2$s%1$s", "", "", "", 7, 4, 100.44));
|
||||
}
|
||||
|
||||
template <typename T> struct make_signed {
|
||||
@ -555,3 +557,8 @@ TEST(printf_test, make_printf_args) {
|
||||
fmt::vsprintf(fmt::basic_string_view<wchar_t>(L"[%d] %s happened"),
|
||||
{fmt::make_printf_args<wchar_t>(n, L"something")}));
|
||||
}
|
||||
|
||||
TEST(printf_test, trailing_percent_non_nul_terminated) {
|
||||
auto p = std::unique_ptr<char>(new char('%'));
|
||||
EXPECT_THROW(fmt::sprintf(fmt::string_view(p.get(), 1)), format_error);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user