diff options
author | Marius Kintel <marius@kintel.net> | 2013-05-22 03:04:22 (GMT) |
---|---|---|
committer | Marius Kintel <marius@kintel.net> | 2013-05-22 03:04:22 (GMT) |
commit | ef9d8a853be1a6d6ca48239fcc79106ba374ee21 (patch) | |
tree | 041fe3424e663a40986208e6829df5e955838e33 /src/expr.cc | |
parent | 470588b296aea880c84071ee53a23f055f9c5bf0 (diff) | |
parent | 71ab237aada8db602045063f0f1c6082ef06972a (diff) |
Merge branch 'master' into issue304
Diffstat (limited to 'src/expr.cc')
-rw-r--r-- | src/expr.cc | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/src/expr.cc b/src/expr.cc index 746c0e3..4355400 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -31,28 +31,29 @@ #include <sstream> #include <algorithm> #include "stl-utils.h" +#include "printutils.h" #include <boost/bind.hpp> #include <boost/foreach.hpp> -Expression::Expression() +Expression::Expression() : recursioncount(0) { } Expression::Expression(const std::string &type, Expression *left, Expression *right) - : type(type) + : type(type), recursioncount(0) { this->children.push_back(left); this->children.push_back(right); } Expression::Expression(const std::string &type, Expression *expr) - : type(type) + : type(type), recursioncount(0) { this->children.push_back(expr); } -Expression::Expression(const Value &val) : const_value(val), type("C") +Expression::Expression(const Value &val) : const_value(val), type("C"), recursioncount(0) { } @@ -61,6 +62,18 @@ Expression::~Expression() std::for_each(this->children.begin(), this->children.end(), del_fun<Expression>()); } +class FuncRecursionGuard +{ +public: + FuncRecursionGuard(const Expression &e) : expr(e) { + expr.recursioncount++; + } + ~FuncRecursionGuard() { expr.recursioncount--; } + bool recursion_detected() const { return (expr.recursioncount > 100); } +private: + const Expression &expr; +}; + Value Expression::evaluate(const Context *context) const { if (this->type == "!") @@ -141,6 +154,12 @@ Value Expression::evaluate(const Context *context) const return Value(); } if (this->type == "F") { + FuncRecursionGuard g(*this); + if (g.recursion_detected()) { + PRINTB("ERROR: Recursion detected calling function '%s'", this->call_funcname); + return Value(); + } + EvalContext c(context, this->call_arguments); return context->evaluate_function(this->call_funcname, &c); } |