mirror of
https://github.com/fmtlib/fmt.git
synced 2024-12-25 06:21:00 +00:00
Don't access a C string past precision in printf (#1595)
This commit is contained in:
parent
7d748a6f82
commit
0463665ef1
@ -141,6 +141,13 @@ template <typename Context> class char_converter {
|
|||||||
void operator()(T) {} // No conversion needed for non-integral types.
|
void operator()(T) {} // No conversion needed for non-integral types.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// An argument visitor that return a pointer to a C string if argument is a
|
||||||
|
// string or null otherwise.
|
||||||
|
template <typename Char> struct get_cstring {
|
||||||
|
template <typename T> const Char* operator()(T) { return nullptr; }
|
||||||
|
const Char* operator()(const Char* s) { return s; }
|
||||||
|
};
|
||||||
|
|
||||||
// Checks if an argument is a valid printf width specifier and sets
|
// Checks if an argument is a valid printf width specifier and sets
|
||||||
// left alignment if it is negative.
|
// left alignment if it is negative.
|
||||||
template <typename Char> class printf_width_handler {
|
template <typename Char> class printf_width_handler {
|
||||||
@ -495,6 +502,13 @@ OutputIt basic_printf_context<OutputIt, Char>::format() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
format_arg arg = get_arg(arg_index);
|
format_arg arg = get_arg(arg_index);
|
||||||
|
if (specs.precision >= 0 && arg.type() == internal::type::cstring_type) {
|
||||||
|
auto str = visit_format_arg(internal::get_cstring<Char>(), arg);
|
||||||
|
auto end = str + specs.precision;
|
||||||
|
auto nul = std::find(str, end, Char());
|
||||||
|
arg = internal::make_arg<basic_printf_context>(basic_string_view<Char>(
|
||||||
|
str, nul != end ? nul - str : specs.precision));
|
||||||
|
}
|
||||||
if (specs.alt && visit_format_arg(internal::is_zero_int(), arg))
|
if (specs.alt && visit_format_arg(internal::is_zero_int(), arg))
|
||||||
specs.alt = false;
|
specs.alt = false;
|
||||||
if (specs.fill[0] == '0') {
|
if (specs.fill[0] == '0') {
|
||||||
|
@ -259,6 +259,11 @@ TEST(PrintfTest, FloatPrecision) {
|
|||||||
EXPECT_PRINTF(buffer, "%.3a", 1234.5678);
|
EXPECT_PRINTF(buffer, "%.3a", 1234.5678);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(PrintfTest, StringPrecision) {
|
||||||
|
char test[] = {'H', 'e', 'l', 'l', 'o'};
|
||||||
|
EXPECT_EQ(fmt::sprintf("%.4s", test), "Hell");
|
||||||
|
}
|
||||||
|
|
||||||
TEST(PrintfTest, IgnorePrecisionForNonNumericArg) {
|
TEST(PrintfTest, IgnorePrecisionForNonNumericArg) {
|
||||||
EXPECT_PRINTF("abc", "%.5s", "abc");
|
EXPECT_PRINTF("abc", "%.5s", "abc");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user