diff --git a/CMakeLists.txt b/CMakeLists.txt
index e0b782f0..49d7879b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -35,7 +35,7 @@ if(CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
endif()
project(Catch2
- VERSION 3.15.0 # CML version placeholder, don't delete
+ VERSION 3.15.1 # CML version placeholder, don't delete
LANGUAGES CXX
HOMEPAGE_URL "https://github.com/catchorg/Catch2"
DESCRIPTION "A modern, C++-native, unit test framework."
diff --git a/docs/release-notes.md b/docs/release-notes.md
index 3df9e690..9f8b0979 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -2,6 +2,7 @@
# Release notes
**Contents**
+[3.15.1](#3151)
[3.15.0](#3150)
[3.14.0](#3140)
[3.13.0](#3130)
@@ -75,6 +76,13 @@
[Even Older versions](#even-older-versions)
+## 3.15.1
+
+### Fixes
+* Fixed potential OOB access when looking for start of broken UTF-8 sequence during linebreaking (#3096)
+* Fixed `TEMPLATE_LIST_TEST_CASE_METHOD` and `CATCH_TEMPLATE_PRODUCT_TEST_CASE` potentially causing ODR violations (#3161)
+
+
## 3.15.0
### Fixes
diff --git a/extras/catch_amalgamated.cpp b/extras/catch_amalgamated.cpp
index e851b09d..baf527f0 100644
--- a/extras/catch_amalgamated.cpp
+++ b/extras/catch_amalgamated.cpp
@@ -6,8 +6,8 @@
// SPDX-License-Identifier: BSL-1.0
-// Catch v3.15.0
-// Generated: 2026-05-12 13:08:21.086523
+// Catch v3.15.1
+// Generated: 2026-06-14 10:51:56.053498
// ----------------------------------------------------------
// This file is an amalgamation of multiple different files.
// You probably shouldn't edit it directly.
@@ -2394,7 +2394,7 @@ namespace Catch {
}
Version const& libraryVersion() {
- static Version version( 3, 15, 0, "", 0 );
+ static Version version( 3, 15, 1, "", 0 );
return version;
}
@@ -8016,8 +8016,8 @@ namespace Catch {
m_it--;
}
// Skip back over UTF-8 continuation bytes to the leading byte
- while ( isUtf8ContinuationByte( *m_it ) ) {
- assert( m_it != m_string->begin() );
+ while ( m_it != m_string->begin() &&
+ isUtf8ContinuationByte( *m_it ) ) {
m_it--;
}
}
diff --git a/extras/catch_amalgamated.hpp b/extras/catch_amalgamated.hpp
index 40fbf485..fc71645c 100644
--- a/extras/catch_amalgamated.hpp
+++ b/extras/catch_amalgamated.hpp
@@ -6,8 +6,8 @@
// SPDX-License-Identifier: BSL-1.0
-// Catch v3.15.0
-// Generated: 2026-05-12 13:08:20.543985
+// Catch v3.15.1
+// Generated: 2026-06-14 10:51:55.600632
// ----------------------------------------------------------
// This file is an amalgamation of multiple different files.
// You probably shouldn't edit it directly.
@@ -7079,42 +7079,42 @@ namespace Catch {
INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_CLASS_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )
#endif
- #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\
- CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
- CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
- CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
- CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
- CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
+#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+ CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
+ CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+ CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
+ namespace {\
template \
- struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName ) { \
- void test();\
- };\
- namespace {\
- namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) {\
- INTERNAL_CATCH_TYPE_GEN \
- INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
- template\
- struct TestNameClass{\
- void reg_tests(){\
- std::size_t index = 0;\
- using expander = std::size_t[];\
- constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
- constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
- constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
- (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + '<' + types_list[index % num_types] + '>', Tags } ), index++)... };/* NOLINT */ \
- }\
- };\
- static const int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
- using TestInit = typename create(Catch::Detail::priority_tag<1>{})), TypeList>::type;\
- TestInit t;\
- t.reg_tests();\
- return 0;\
- }(); \
- }\
- }\
- CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
- template \
- void TestName::test()
+ struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName ) { \
+ void test();\
+ };\
+ namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) {\
+ INTERNAL_CATCH_TYPE_GEN \
+ INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\
+ template\
+ struct TestNameClass{\
+ void reg_tests(){\
+ std::size_t index = 0;\
+ using expander = std::size_t[];\
+ constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
+ constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
+ constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
+ (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + '<' + types_list[index % num_types] + '>', Tags } ), index++)... };/* NOLINT */ \
+ }\
+ };\
+ static const int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
+ using TestInit = typename create(Catch::Detail::priority_tag<1>{})), TypeList>::type;\
+ TestInit t;\
+ t.reg_tests();\
+ return 0;\
+ }(); \
+ }\
+ }\
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
+ template \
+ void TestName::test()
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
@@ -7132,37 +7132,37 @@ namespace Catch {
INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) )
#endif
- #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
- CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
- CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
- CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
- CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
- CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS \
+#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+ CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+ CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
+ CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS \
+ namespace {\
template \
struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName ) { \
void test();\
};\
- namespace {\
- namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
- INTERNAL_CATCH_TYPE_GEN\
- template\
- struct TestNameClass{\
- void reg_tests(){\
- size_t index = 0;\
- using expander = size_t[];\
- (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName##_catch_sr, Catch::NameAndTags{ Name " - " INTERNAL_CATCH_STRINGIZE(TmplList) " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */ \
- }\
- };\
- static const int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
- using TestInit = typename convert::type;\
- TestInit t;\
- t.reg_tests();\
- return 0;\
- }(); \
- }}\
- CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
- template \
- void TestName::test()
+ namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
+ INTERNAL_CATCH_TYPE_GEN\
+ template\
+ struct TestNameClass{\
+ void reg_tests(){\
+ size_t index = 0;\
+ using expander = size_t[];\
+ (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName##_catch_sr, Catch::NameAndTags{ Name " - " INTERNAL_CATCH_STRINGIZE(TmplList) " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */ \
+ }\
+ };\
+ static const int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
+ using TestInit = typename convert::type;\
+ TestInit t;\
+ t.reg_tests();\
+ return 0;\
+ }(); \
+ }}\
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
+ template \
+ void TestName::test()
#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \
INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEMPLATE_TEST_ ), ClassName, Name, Tags, TmplList )
@@ -7570,7 +7570,7 @@ namespace Catch {
#define CATCH_VERSION_MAJOR 3
#define CATCH_VERSION_MINOR 15
-#define CATCH_VERSION_PATCH 0
+#define CATCH_VERSION_PATCH 1
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED
diff --git a/meson.build b/meson.build
index 2e390b52..57408666 100644
--- a/meson.build
+++ b/meson.build
@@ -8,7 +8,7 @@
project(
'catch2',
'cpp',
- version: '3.15.0', # CML version placeholder, don't delete
+ version: '3.15.1', # CML version placeholder, don't delete
license: 'BSL-1.0',
meson_version: '>=0.54.1',
)
diff --git a/src/catch2/catch_version.cpp b/src/catch2/catch_version.cpp
index eb385fe2..c815dba5 100644
--- a/src/catch2/catch_version.cpp
+++ b/src/catch2/catch_version.cpp
@@ -36,7 +36,7 @@ namespace Catch {
}
Version const& libraryVersion() {
- static Version version( 3, 15, 0, "", 0 );
+ static Version version( 3, 15, 1, "", 0 );
return version;
}
diff --git a/src/catch2/catch_version_macros.hpp b/src/catch2/catch_version_macros.hpp
index 41fc51af..f60b3199 100644
--- a/src/catch2/catch_version_macros.hpp
+++ b/src/catch2/catch_version_macros.hpp
@@ -10,6 +10,6 @@
#define CATCH_VERSION_MAJOR 3
#define CATCH_VERSION_MINOR 15
-#define CATCH_VERSION_PATCH 0
+#define CATCH_VERSION_PATCH 1
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED