summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2016-03-24 12:49:46 (GMT)
committerCMake Topic Stage <kwrobot@kitware.com>2016-03-24 12:49:46 (GMT)
commit6d36fc8341aa7361a5786e78a19d9bab71ee42d2 (patch)
tree0145426406b5fbdb0254dfbd80880f6659f1dc7e
parent917d49ed93b7b43ac3508dbd81f0645433880724 (diff)
parentc61040282557ba268e144ffa5e2d1935b5991d8d (diff)
downloadCMake-6d36fc8341aa7361a5786e78a19d9bab71ee42d2.zip
CMake-6d36fc8341aa7361a5786e78a19d9bab71ee42d2.tar.gz
CMake-6d36fc8341aa7361a5786e78a19d9bab71ee42d2.tar.bz2
Merge topic 'fix-variable_watch-reallocation'
c6104028 Avoid occasional use-after-free when a variable watch is executed
-rw-r--r--Source/cmMakefile.cxx23
-rw-r--r--Source/cmVariableWatch.cxx4
-rw-r--r--Source/cmVariableWatch.h2
3 files changed, 19 insertions, 10 deletions
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 1df5cec..aa6f7c8 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -2503,15 +2503,22 @@ const char* cmMakefile::GetDefinition(const std::string& name) const
cmVariableWatch* vv = this->GetVariableWatch();
if ( vv && !this->SuppressWatches )
{
- if ( def )
- {
- vv->VariableAccessed(name, cmVariableWatch::VARIABLE_READ_ACCESS,
- def, this);
- }
- else
- {
+ bool const watch_function_executed =
vv->VariableAccessed(name,
- cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS, def, this);
+ def ? cmVariableWatch::VARIABLE_READ_ACCESS
+ : cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS,
+ def, this);
+
+ if (watch_function_executed)
+ {
+ // A callback was executed and may have caused re-allocation of the
+ // variable storage. Look it up again for now.
+ // FIXME: Refactor variable storage to avoid this problem.
+ def = this->StateSnapshot.GetDefinition(name);
+ if(!def)
+ {
+ def = this->GetState()->GetInitializedCacheValue(name);
+ }
}
}
#endif
diff --git a/Source/cmVariableWatch.cxx b/Source/cmVariableWatch.cxx
index 57dde31..a200718 100644
--- a/Source/cmVariableWatch.cxx
+++ b/Source/cmVariableWatch.cxx
@@ -96,7 +96,7 @@ void cmVariableWatch::RemoveWatch(const std::string& variable,
}
}
-void cmVariableWatch::VariableAccessed(const std::string& variable,
+bool cmVariableWatch::VariableAccessed(const std::string& variable,
int access_type,
const char* newValue,
const cmMakefile* mf) const
@@ -112,5 +112,7 @@ void cmVariableWatch::VariableAccessed(const std::string& variable,
(*it)->Method(variable, access_type, (*it)->ClientData,
newValue, mf);
}
+ return true;
}
+ return false;
}
diff --git a/Source/cmVariableWatch.h b/Source/cmVariableWatch.h
index 0ca4a55..2f082af 100644
--- a/Source/cmVariableWatch.h
+++ b/Source/cmVariableWatch.h
@@ -42,7 +42,7 @@ public:
/**
* This method is called when variable is accessed
*/
- void VariableAccessed(const std::string& variable, int access_type,
+ bool VariableAccessed(const std::string& variable, int access_type,
const char* newValue, const cmMakefile* mf) const;
/**