aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/eval.cc
diff options
context:
space:
mode:
authoreldritch horrors <pennae@lix.systems>2024-03-04 07:35:20 +0100
committereldritch horrors <pennae@lix.systems>2024-03-04 07:35:20 +0100
commit96f1a404d08d1dd00ef395bcdc53c7599c860ecf (patch)
treec2c10849ccfa865ae649be873fa9ed0d6d4d4da6 /src/libexpr/eval.cc
parente1b1e6f7abb62b7e86a1d12aead1bd931089cd7a (diff)
Merge pull request #9617 from 9999years/stack-overflow-segfault
Fix segfault on infinite recursion in some cases (cherry picked from commit bf1b294bd81ca76c5ec9fe3ecd52196bf52a8300) Change-Id: Id137541426ec8536567835953fccf986a3aebf16
Diffstat (limited to 'src/libexpr/eval.cc')
-rw-r--r--src/libexpr/eval.cc18
1 files changed, 18 insertions, 0 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 98fc01368..deb5ea2b3 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -1525,9 +1525,27 @@ void ExprLambda::eval(EvalState & state, Env & env, Value & v)
v.mkLambda(&env, this);
}
+namespace {
+/** Increments a count on construction and decrements on destruction.
+ */
+class CallDepth {
+ size_t & count;
+public:
+ CallDepth(size_t & count) : count(count) {
+ ++count;
+ }
+ ~CallDepth() {
+ --count;
+ }
+};
+};
void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & vRes, const PosIdx pos)
{
+ if (callDepth > evalSettings.maxCallDepth)
+ error("stack overflow; max-call-depth exceeded").atPos(pos).template debugThrow<EvalError>();
+ CallDepth _level(callDepth);
+
auto trace = evalSettings.traceFunctionCalls
? std::make_unique<FunctionCallTrace>(positions[pos])
: nullptr;