]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Fix past-the-end increment in std::format [PR110862]
authorJonathan Wakely <jwakely@redhat.com>
Thu, 3 Aug 2023 07:45:43 +0000 (08:45 +0100)
committerJonathan Wakely <jwakely@redhat.com>
Mon, 7 Aug 2023 21:09:10 +0000 (22:09 +0100)
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.

libstdc++-v3/include/std/format
libstdc++-v3/testsuite/std/format/string.cc

index 1e0ef612ddd8865425c3d356ae6965943ed09b50..0debbae5ba86f8db4c59b88bbe4d75bed4f51226 100644 (file)
@@ -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;
index d28135ec260b3b0d7e93af481da686b8d7f34774..6a45237b8c4d5723465d53cac55842663a2fb005 100644 (file)
@@ -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();