From eb7167d456b8ef2dad3846ca2ba6438b060518c9 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Wed, 18 Mar 2015 16:54:16 -0400 Subject: [PATCH] Don't crash on cyclic references between rule bindings. Fixes #902. This dynamically detects cycles. I like this approach less than detecting them statically when parsing rules [1], but it has the advantage that it doesn't break existing ninja manifest files. It has the disadvantage that it slows down manifest_parser_perftest by 3.9%. 1: https://github.com/martine/ninja/commit/cc6f54d6d436047 --- src/graph.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/graph.cc b/src/graph.cc index b19dc85..41055ec 100644 --- a/src/graph.cc +++ b/src/graph.cc @@ -226,6 +226,7 @@ struct EdgeEnv : public Env { vector::iterator end, char sep); + vector lookups_; Edge* edge_; EscapeKind escape_in_out_; }; @@ -243,8 +244,19 @@ string EdgeEnv::LookupVariable(const string& var) { ' '); } + vector::const_iterator it; + if ((it = find(lookups_.begin(), lookups_.end(), var)) != lookups_.end()) { + string cycle; + for (; it != lookups_.end(); ++it) + cycle.append(*it + " -> "); + cycle.append(var); + Fatal(("cycle in rule variables: " + cycle).c_str()); + } + // See notes on BindingEnv::LookupWithFallback. const EvalString* eval = edge_->rule_->GetBinding(var); + if (eval) + lookups_.push_back(var); return edge_->env_->LookupWithFallback(var, eval, this); } -- 2.7.4