llvm/llvm-project

[libc++] `std::format` reads past the 0 terminator in `char[N]` arrays

Closed this issue · 1 comments

Reproducer

If one passes a fixed size char - array containing a 0-terminated string to std::format, the entire array minus one character is added to the result, instead of just the part until the null terminator. This not only seemingly violates [format.formatter.spec]/2.2, but also doesn't match the behavior of MS-STL or libstdc++. (And only formatting 49 characters out of a 50 character array seems buggy anyway.)

The issue is reproducible with all versions of libc++ that shipped with clang since <format> was added, including current trunk on godbolt.

See here:

// Char pointer
template <class _Context, class _Tp>
requires(same_as<typename _Context::char_type*, _Tp> || same_as<const typename _Context::char_type*, _Tp>)
consteval __arg_t __determine_arg_t() {
return __arg_t::__const_char_type_ptr;
}
// Char array
template <class _Context, class _Tp>
requires(is_array_v<_Tp> && same_as<_Tp, typename _Context::char_type[extent_v<_Tp>]>)
consteval __arg_t __determine_arg_t() {
return __arg_t::__string_view;
}

Per [format.arg]/6, char arrays should be converted to char pointers first.

CC @mordante