aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShinichiro Hamaji <shinichiro.hamaji@gmail.com>2015-11-30 19:03:53 +0900
committerShinichiro Hamaji <shinichiro.hamaji@gmail.com>2015-11-30 19:03:53 +0900
commit28da2379c3b819088f0a503fcd0bfdd27ab40879 (patch)
treec887743ca9af92ec12c703678d329c21fb28ce51
parent77be80dde684e25ba057dd5082d569178a4b2e39 (diff)
downloadandroid_build_kati-28da2379c3b819088f0a503fcd0bfdd27ab40879.tar.gz
android_build_kati-28da2379c3b819088f0a503fcd0bfdd27ab40879.tar.bz2
android_build_kati-28da2379c3b819088f0a503fcd0bfdd27ab40879.zip
[C++] Explicitly disallow $(shell) in other make constructs
-rw-r--r--eval.cc3
-rw-r--r--eval.h12
-rw-r--r--expr.cc8
-rw-r--r--func.cc10
-rw-r--r--testcase/strip_and_shell.mk1
5 files changed, 32 insertions, 2 deletions
diff --git a/eval.cc b/eval.cc
index 2ba4a56..3c0eae2 100644
--- a/eval.cc
+++ b/eval.cc
@@ -41,7 +41,8 @@ Evaluator::Evaluator(const Vars* vars)
vars_(new Vars()),
last_rule_(NULL),
current_scope_(NULL),
- avoid_io_(false) {
+ avoid_io_(false),
+ eval_depth_(0) {
}
Evaluator::~Evaluator() {
diff --git a/eval.h b/eval.h
index 3ebb21b..6bc21b9 100644
--- a/eval.h
+++ b/eval.h
@@ -92,6 +92,14 @@ class Evaluator {
return used_undefined_vars_;
}
+ int eval_depth() const { return eval_depth_; }
+ void IncrementEvalDepth() {
+ eval_depth_++;
+ }
+ void DecrementEvalDepth() {
+ eval_depth_--;
+ }
+
private:
Var* EvalRHS(Symbol lhs, Value* rhs, StringPiece orig_rhs, AssignOp op,
bool is_override = false);
@@ -112,6 +120,10 @@ class Evaluator {
bool is_bootstrap_;
bool avoid_io_;
+ // This value tracks the nest level of make expressions. For
+ // example, $(YYY) in $(XXX $(YYY)) is evaluated with depth==2.
+ // This will be used to disallow $(shell) in other make constructs.
+ int eval_depth_;
// Commands which should run at ninja-time (i.e., info, warning, and
// error).
vector<string> delayed_output_commands_;
diff --git a/expr.cc b/expr.cc
index e43d189..d0d3e38 100644
--- a/expr.cc
+++ b/expr.cc
@@ -152,7 +152,9 @@ class VarRef : public Value {
}
virtual void Eval(Evaluator* ev, string* s) const override {
+ ev->IncrementEvalDepth();
const string&& name = name_->Eval(ev);
+ ev->DecrementEvalDepth();
Var* v = ev->LookupVar(Intern(name));
v->Eval(ev, s);
}
@@ -177,11 +179,13 @@ class VarSubst : public Value {
}
virtual void Eval(Evaluator* ev, string* s) const override {
+ ev->IncrementEvalDepth();
const string&& name = name_->Eval(ev);
Var* v = ev->LookupVar(Intern(name));
- const string&& value = v->Eval(ev);
const string&& pat_str = pat_->Eval(ev);
const string&& subst = subst_->Eval(ev);
+ ev->DecrementEvalDepth();
+ const string&& value = v->Eval(ev);
WordWriter ww(s);
Pattern pat(pat_str);
for (StringPiece tok : WordScanner(value)) {
@@ -216,7 +220,9 @@ class Func : public Value {
virtual void Eval(Evaluator* ev, string* s) const override {
LOG("Invoke func %s(%s)", name(), JoinValues(args_, ",").c_str());
+ ev->IncrementEvalDepth();
fi_->func(args_, ev, s);
+ ev->DecrementEvalDepth();
}
virtual string DebugString_() const override {
diff --git a/func.cc b/func.cc
index 33c5013..39af0e9 100644
--- a/func.cc
+++ b/func.cc
@@ -546,6 +546,11 @@ bool ShouldStoreCommandResult(StringPiece cmd) {
void ShellFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
string cmd = args[0]->Eval(ev);
if (ev->avoid_io() && !HasNoIoInShellScript(cmd)) {
+ if (ev->eval_depth() > 1) {
+ ERROR("%s:%d: kati doesn't support passing results of $(shell) "
+ "to other make constructs: %s",
+ LOCF(ev->loc()), cmd.c_str());
+ }
StripShellComment(&cmd);
*s += "$(";
*s += cmd;
@@ -609,12 +614,16 @@ void CallFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
Intern(tmpvar_name), av[i-1].get()));
}
}
+
+ ev->DecrementEvalDepth();
func->Eval(ev, s);
+ ev->IncrementEvalDepth();
}
void ForeachFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
const string&& varname = args[0]->Eval(ev);
const string&& list = args[1]->Eval(ev);
+ ev->DecrementEvalDepth();
WordWriter ww(s);
for (StringPiece tok : WordScanner(list)) {
unique_ptr<SimpleVar> v(new SimpleVar(
@@ -623,6 +632,7 @@ void ForeachFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
ww.MaybeAddWhitespace();
args[2]->Eval(ev, s);
}
+ ev->IncrementEvalDepth();
}
void OriginFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
diff --git a/testcase/strip_and_shell.mk b/testcase/strip_and_shell.mk
index db1bbf2..cb550f3 100644
--- a/testcase/strip_and_shell.mk
+++ b/testcase/strip_and_shell.mk
@@ -1,3 +1,4 @@
+# TODO(c-ninja): $(shell) in another make expression is not supported.
test:
echo $(strip $(shell pwd))