summaryrefslogtreecommitdiff
path: root/src/expr.cc
diff options
context:
space:
mode:
authorMarius Kintel <marius@kintel.net>2013-05-13 20:27:17 (GMT)
committerMarius Kintel <marius@kintel.net>2013-05-13 20:27:17 (GMT)
commitee6f149dd0d9bcef0cb94cef154ed32f308c23e1 (patch)
tree28542d1aa602d31ffbced210bd881249242f5c5f /src/expr.cc
parent8c532d525203d6cd0fc8ab200a4dea1dccd03dd6 (diff)
bugfix: Fixed recursion crash (#346)
Diffstat (limited to 'src/expr.cc')
-rw-r--r--src/expr.cc21
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);
}
contact: Jan Huwald // Impressum