diff options
author | Marius Kintel <marius@kintel.net> | 2013-05-13 20:27:17 (GMT) |
---|---|---|
committer | Marius Kintel <marius@kintel.net> | 2013-05-13 20:27:17 (GMT) |
commit | ee6f149dd0d9bcef0cb94cef154ed32f308c23e1 (patch) | |
tree | 28542d1aa602d31ffbced210bd881249242f5c5f /src/expr.cc | |
parent | 8c532d525203d6cd0fc8ab200a4dea1dccd03dd6 (diff) |
bugfix: Fixed recursion crash (#346)
Diffstat (limited to 'src/expr.cc')
-rw-r--r-- | src/expr.cc | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/src/expr.cc b/src/expr.cc index 746c0e3..9eaeeef 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -31,6 +31,7 @@ #include <sstream> #include <algorithm> #include "stl-utils.h" +#include "printutils.h" #include <boost/bind.hpp> #include <boost/foreach.hpp> @@ -40,7 +41,7 @@ Expression::Expression() 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); @@ -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); } |