diff --git a/include/fmt/printf.h b/include/fmt/printf.h index a7213d01..19e5bbbc 100644 --- a/include/fmt/printf.h +++ b/include/fmt/printf.h @@ -494,11 +494,13 @@ void vprintf(buffer& buf, basic_string_view format, } if (specs.precision >= 0 && arg.type() == type::cstring_type) { auto str = arg.visit(get_cstring()); - auto str_end = str + specs.precision; - auto nul = std::find(str, str_end, Char()); - auto sv = basic_string_view( - str, to_unsigned(nul != str_end ? nul - str : specs.precision)); - arg = sv; + if (str) { + auto str_end = str + specs.precision; + auto nul = std::find(str, str_end, Char()); + auto sv = basic_string_view( + str, to_unsigned(nul != str_end ? nul - str : specs.precision)); + arg = sv; + } } if (specs.fill_unit() == '0') { if (is_arithmetic_type(arg.type()) && specs.align() != align::left) { diff --git a/test/printf-test.cc b/test/printf-test.cc index db877d09..dbd46065 100644 --- a/test/printf-test.cc +++ b/test/printf-test.cc @@ -544,6 +544,9 @@ TEST(printf_test, string) { const char* null_str = nullptr; EXPECT_PRINTF("(null)", "%s", null_str); EXPECT_PRINTF(" (null)", "%10s", null_str); + // A precision must not apply pointer arithmetic to a null string argument. + EXPECT_PRINTF("(null)", "%.3s", null_str); + EXPECT_PRINTF("(null)", "%.0s", null_str); } TEST(printf_test, pointer) {