summaryrefslogtreecommitdiff
path: root/src/expr.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/expr.cc')
-rw-r--r--src/expr.cc27
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);
}
contact: Jan Huwald // Impressum