diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2023-08-03 08:45:43 +0100 |
---|---|---|
committer | Jonathan Wakely <jwakely@redhat.com> | 2023-08-07 22:09:10 +0100 |
commit | 5d87f71bb462ccb78dd3d9d810ea08d96869cb4b (patch) | |
tree | 9f3d9355979598043fc0c298e91a3c9b38212e67 | |
parent | eff0e7a4ae31d1e4e64ae37bbc10d073d8579255 (diff) | |
download | gcc-5d87f71bb462ccb78dd3d9d810ea08d96869cb4b.zip gcc-5d87f71bb462ccb78dd3d9d810ea08d96869cb4b.tar.gz gcc-5d87f71bb462ccb78dd3d9d810ea08d96869cb4b.tar.bz2 |
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.
-rw-r--r-- | libstdc++-v3/include/std/format | 4 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/std/format/string.cc | 13 |
2 files changed, 16 insertions, 1 deletions
diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format index 1e0ef61..0debbae 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 d28135e..6a45237 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(); |