[libcxx-commits] [libcxx] 8930d04 - [libc++][format] Fixes out of bounds access.
Mark de Wever via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Aug 30 08:41:03 PDT 2023
Author: Mark de Wever
Date: 2023-08-30T17:40:58+02:00
New Revision: 8930d04d5580c6a2cf04545c87387cd150cd7b46
URL: https://github.com/llvm/llvm-project/commit/8930d04d5580c6a2cf04545c87387cd150cd7b46
DIFF: https://github.com/llvm/llvm-project/commit/8930d04d5580c6a2cf04545c87387cd150cd7b46.diff
LOG: [libc++][format] Fixes out of bounds access.
Fixes https://llvm.org/PR65011
Reviewed By: #libc, ldionne
Differential Revision: https://reviews.llvm.org/D158940
Added:
Modified:
libcxx/include/__format/format_functions.h
libcxx/test/std/utilities/format/format.functions/format_tests.h
libcxx/test/std/utilities/format/format.functions/vformat.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/include/__format/format_functions.h b/libcxx/include/__format/format_functions.h
index 27ec0a295f4f43..bb62c1ce10c15c 100644
--- a/libcxx/include/__format/format_functions.h
+++ b/libcxx/include/__format/format_functions.h
@@ -245,6 +245,9 @@ __handle_replacement_field(_Iterator __begin, _Iterator __end,
using _CharT = iter_value_t<_Iterator>;
__format::__parse_number_result __r = __format::__parse_arg_id(__begin, __end, __parse_ctx);
+ if (__r.__last == __end)
+ std::__throw_format_error("The argument index should end with a ':' or a '}'");
+
bool __parse = *__r.__last == _CharT(':');
switch (*__r.__last) {
case _CharT(':'):
diff --git a/libcxx/test/std/utilities/format/format.functions/format_tests.h b/libcxx/test/std/utilities/format/format.functions/format_tests.h
index 7a9cdaab7e93e8..0a5c6649240d68 100644
--- a/libcxx/test/std/utilities/format/format.functions/format_tests.h
+++ b/libcxx/test/std/utilities/format/format.functions/format_tests.h
@@ -3145,8 +3145,13 @@ void format_tests(TestFunction check, ExceptionTest check_exception) {
// *** Test invalid format strings ***
check_exception("The format string terminates at a '{'", SV("{"));
+ check_exception("The argument index value is too large for the number of arguments supplied", SV("{:"));
check_exception("The replacement field misses a terminating '}'", SV("{:"), 42);
+ check_exception("The argument index should end with a ':' or a '}'", SV("{0"));
+ check_exception("The argument index value is too large for the number of arguments supplied", SV("{0:"));
+ check_exception("The replacement field misses a terminating '}'", SV("{0:"), 42);
+
check_exception("The format string contains an invalid escape sequence", SV("}"));
check_exception("The format string contains an invalid escape sequence", SV("{:}-}"), 42);
diff --git a/libcxx/test/std/utilities/format/format.functions/vformat.pass.cpp b/libcxx/test/std/utilities/format/format.functions/vformat.pass.cpp
index 6943ddc2f968ec..e16d50f18284f7 100644
--- a/libcxx/test/std/utilities/format/format.functions/vformat.pass.cpp
+++ b/libcxx/test/std/utilities/format/format.functions/vformat.pass.cpp
@@ -50,6 +50,17 @@ auto test_exception =
};
int main(int, char**) {
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ // reproducer of https://llvm.org/PR65011
+ try {
+ const char fmt[] = {'{', '0'};
+ char buf[4096];
+ [[maybe_unused]] auto ignored =
+ std::vformat_to(buf, std::string_view{fmt, fmt + sizeof(fmt)}, std::make_format_args());
+ } catch (...) {
+ }
+#endif // !defined(TEST_HAS_NO_EXCEPTIONS)
+
format_tests<char, execution_modus::full>(test, test_exception);
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
More information about the libcxx-commits
mailing list