diff options
author | eldritch horrors <pennae@lix.systems> | 2024-03-04 07:35:20 +0100 |
---|---|---|
committer | eldritch horrors <pennae@lix.systems> | 2024-03-04 07:35:20 +0100 |
commit | 96f1a404d08d1dd00ef395bcdc53c7599c860ecf (patch) | |
tree | c2c10849ccfa865ae649be873fa9ed0d6d4d4da6 /src/libexpr/eval.cc | |
parent | e1b1e6f7abb62b7e86a1d12aead1bd931089cd7a (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.cc | 18 |
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; |