libstdc++: Fix use-after-free in std::format [PR119671]
When formatting floating-point values to wide strings there's a case where we invalidate a std::wstring buffer while a std::wstring_view is still referring to it. libstdc++-v3/ChangeLog: PR libstdc++/119671 * include/std/format (__formatter_fp::format): Do not invalidate __wstr unless _M_localized returns a valid string. * testsuite/std/format/functions/format.cc: Check wide string formatting of floating-point types with classic locale. Reviewed-by: Tomasz Kaminski <tkaminsk@redhat.com>
This commit is contained in:
parent
a9bbb60b7c
commit
e33b62eed7
2 changed files with 15 additions and 3 deletions
|
@ -1838,9 +1838,9 @@ namespace __format
|
|||
|
||||
if (_M_spec._M_localized && __builtin_isfinite(__v))
|
||||
{
|
||||
__wstr = _M_localize(__str, __expc, __fc.locale());
|
||||
if (!__wstr.empty())
|
||||
__str = __wstr;
|
||||
auto __s = _M_localize(__str, __expc, __fc.locale());
|
||||
if (!__s.empty())
|
||||
__str = __wstr = std::move(__s);
|
||||
}
|
||||
|
||||
size_t __width = _M_spec._M_get_width(__fc);
|
||||
|
|
|
@ -370,6 +370,18 @@ test_wchar()
|
|||
// P2909R4 Fix formatting of code units as integers (Dude, where’s my char?)
|
||||
s = std::format(L"{:d} {:d}", wchar_t(-1), char(-1));
|
||||
VERIFY( s.find('-') == std::wstring::npos );
|
||||
|
||||
auto ws = std::format(L"{:L}", 0.5);
|
||||
VERIFY( ws == L"0.5" );
|
||||
// The default C locale.
|
||||
std::locale cloc = std::locale::classic();
|
||||
// PR libstdc++/119671 use-after-free formatting floating-point to wstring
|
||||
ws = std::format(cloc, L"{:L}", 0.5);
|
||||
VERIFY( ws == L"0.5" );
|
||||
// A locale with no name, but with the same facets as the C locale.
|
||||
std::locale locx(cloc, &std::use_facet<std::ctype<char>>(cloc));
|
||||
ws = std::format(locx, L"{:L}", 0.5);
|
||||
VERIFY( ws == L"0.5" );
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Add table
Reference in a new issue