From c5c688820c919e202304b885df1c5a920ff7eb4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Sat, 26 Oct 2019 21:07:38 +0200 Subject: [PATCH] Document that matcher combinators (&&, ||, !) do not take ownership Closes #1781 --- docs/matchers.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/docs/matchers.md b/docs/matchers.md index af2071e3..bdb7dac4 100644 --- a/docs/matchers.md +++ b/docs/matchers.md @@ -17,7 +17,7 @@ For example, to assert that a string ends with a certain substring: using Catch::Matchers::EndsWith; // or Catch::EndsWith std::string str = getStringFromSomewhere(); REQUIRE_THAT( str, EndsWith( "as a service" ) ); - ``` +``` The matcher objects can take multiple arguments, allowing more fine tuning. The built-in string matchers, for example, take a second argument specifying whether the comparison is @@ -35,6 +35,22 @@ REQUIRE_THAT( str, (StartsWith( "Big data" ) && !Contains( "web scale" ) ) ); ``` +_The combining operators do not take ownership of the matcher objects. +This means that if you store the combined object, you have to ensure that +the matcher objects outlive its last use. What this means is that code +like this leads to a use-after-free and (hopefully) a crash:_ + +```cpp +TEST_CASE("Bugs, bugs, bugs", "[Bug]"){ + std::string str = "Bugs as a service"; + + auto match_expression = Catch::EndsWith( "as a service" ) || + (Catch::StartsWith( "Big data" ) && !Catch::Contains( "web scale" ) ); + REQUIRE_THAT(str, match_expression); +} +``` + + ## Built in matchers Catch2 provides some matchers by default. They can be found in the `Catch::Matchers::foo` namespace and are imported into the `Catch`