From: Jonathan Wakely Date: Thu, 3 Aug 2023 07:45:43 +0000 (+0100) Subject: libstdc++: Fix past-the-end increment in std::format [PR110862] X-Git-Tag: basepoints/gcc-15~7073 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5d87f71bb462ccb78dd3d9d810ea08d96869cb4b;p=thirdparty%2Fgcc.git libstdc++: Fix past-the-end increment in std::format [PR110862] At the end of a replacement field we should check that the closing brace is actually present before incrementing past it. libstdc++-v3/ChangeLog: PR libstdc++/110862 * include/std/format (_Scanner::_M_on_replacement_field): Check for expected '}' before incrementing iterator. * testsuite/std/format/string.cc: Check "{0:{0}" format string. --- diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format index 1e0ef612ddd8..0debbae5ba86 100644 --- a/libstdc++-v3/include/std/format +++ b/libstdc++-v3/include/std/format @@ -3534,7 +3534,9 @@ namespace __format _M_pc.advance_to(__ptr); } _M_format_arg(__id); - _M_pc.advance_to(_M_pc.begin() + 1); // Move past '}' + if (begin() == end() || *begin() != '}') + __format::__unmatched_left_brace_in_format_string(); + _M_pc.advance_to(begin() + 1); // Move past '}' } constexpr virtual void _M_format_arg(size_t __id) = 0; diff --git a/libstdc++-v3/testsuite/std/format/string.cc b/libstdc++-v3/testsuite/std/format/string.cc index d28135ec260b..6a45237b8c4d 100644 --- a/libstdc++-v3/testsuite/std/format/string.cc +++ b/libstdc++-v3/testsuite/std/format/string.cc @@ -128,6 +128,19 @@ test_format_spec() VERIFY( ! is_format_string_for("{:9999999}", 1) ); } +void +test_pr110862() +{ + try { + // PR libstdc++/110862 out-of-bounds read on invalid format string + (void) std::vformat("{0:{0}", std::make_format_args(1)); + VERIFY( false ); + } catch (const std::format_error& e) { + std::string_view what = e.what(); + VERIFY( what.find("unmatched left brace") != what.npos ); + } +} + int main() { test_no_args();