diff options
author | Shinichiro Hamaji <shinichiro.hamaji@gmail.com> | 2015-11-30 19:03:53 +0900 |
---|---|---|
committer | Shinichiro Hamaji <shinichiro.hamaji@gmail.com> | 2015-11-30 19:03:53 +0900 |
commit | 28da2379c3b819088f0a503fcd0bfdd27ab40879 (patch) | |
tree | c887743ca9af92ec12c703678d329c21fb28ce51 | |
parent | 77be80dde684e25ba057dd5082d569178a4b2e39 (diff) | |
download | android_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.cc | 3 | ||||
-rw-r--r-- | eval.h | 12 | ||||
-rw-r--r-- | expr.cc | 8 | ||||
-rw-r--r-- | func.cc | 10 | ||||
-rw-r--r-- | testcase/strip_and_shell.mk | 1 |
5 files changed, 32 insertions, 2 deletions
@@ -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() { @@ -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_; @@ -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 { @@ -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)) |