cmConditionEvaluator: Fix matching of `CMAKE_MATCH_*` values (#15944)
While evaluating `if(MATCHES)` we get a `const char*` pointer to the string to be matched. On code like if(CMAKE_MATCH_COUNT MATCHES "Y") the string to be matched may be owned by our own result variables. We must move the value to our own buffer before clearing them. Otherwise we risk reading freed storage.
This commit is contained in:
parent
656768cffe
commit
6ffc432367
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include "cmConditionEvaluator.h"
|
#include "cmConditionEvaluator.h"
|
||||||
#include "cmOutputConverter.h"
|
#include "cmOutputConverter.h"
|
||||||
|
#include "cmAlgorithms.h"
|
||||||
|
|
||||||
cmConditionEvaluator::cmConditionEvaluator(cmMakefile& makefile,
|
cmConditionEvaluator::cmConditionEvaluator(cmMakefile& makefile,
|
||||||
const cmListFileContext &context,
|
const cmListFileContext &context,
|
||||||
|
@ -578,6 +579,7 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList &newArgs,
|
||||||
cmake::MessageType &status)
|
cmake::MessageType &status)
|
||||||
{
|
{
|
||||||
int reducible;
|
int reducible;
|
||||||
|
std::string def_buf;
|
||||||
const char *def;
|
const char *def;
|
||||||
const char *def2;
|
const char *def2;
|
||||||
do
|
do
|
||||||
|
@ -594,6 +596,14 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList &newArgs,
|
||||||
IsKeyword("MATCHES", *argP1))
|
IsKeyword("MATCHES", *argP1))
|
||||||
{
|
{
|
||||||
def = this->GetVariableOrString(*arg);
|
def = this->GetVariableOrString(*arg);
|
||||||
|
if (def != arg->c_str() // yes, we compare the pointer value
|
||||||
|
&& cmHasLiteralPrefix(arg->GetValue(), "CMAKE_MATCH_"))
|
||||||
|
{
|
||||||
|
// The string to match is owned by our match result variables.
|
||||||
|
// Move it to our own buffer before clearing them.
|
||||||
|
def_buf = def;
|
||||||
|
def = def_buf.c_str();
|
||||||
|
}
|
||||||
const char* rex = argP2->c_str();
|
const char* rex = argP2->c_str();
|
||||||
this->Makefile.ClearMatches();
|
this->Makefile.ClearMatches();
|
||||||
cmsys::RegularExpression regEntry;
|
cmsys::RegularExpression regEntry;
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
foreach(n 0 1 2 3 4 5 6 7 8 9 COUNT)
|
||||||
|
if(CMAKE_MATCH_${n} MATCHES "x")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
|
@ -5,5 +5,7 @@ run_cmake(IsDirectory)
|
||||||
run_cmake(IsDirectoryLong)
|
run_cmake(IsDirectoryLong)
|
||||||
run_cmake(elseif-message)
|
run_cmake(elseif-message)
|
||||||
|
|
||||||
|
run_cmake(MatchesSelf)
|
||||||
|
|
||||||
run_cmake(TestNameThatExists)
|
run_cmake(TestNameThatExists)
|
||||||
run_cmake(TestNameThatDoesNotExist)
|
run_cmake(TestNameThatDoesNotExist)
|
||||||
|
|
Loading…
Reference in New Issue