From 87df7f7c43d746503773aeafd104f566001e87c6 Mon Sep 17 00:00:00 2001 From: Amr Hesham Date: Fri, 7 Apr 2023 01:50:02 +0200 Subject: [PATCH] Explorer: Fuzzer issue around infinite recursion (#2741) I limited the stack size to 1K we can change it or make it dynamic from CLI later Closes #2733 --- explorer/interpreter/action_stack.h | 2 ++ explorer/interpreter/interpreter.cpp | 4 ++++ .../fail_recursion_stackoverflow.carbon | 20 +++++++++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 explorer/testdata/function/fail_recursion_stackoverflow.carbon diff --git a/explorer/interpreter/action_stack.h b/explorer/interpreter/action_stack.h index 383dd8562cc6..4f4b686f9e44 100644 --- a/explorer/interpreter/action_stack.h +++ b/explorer/interpreter/action_stack.h @@ -119,6 +119,8 @@ class ActionStack { void Pop() { todo_.Pop(); } + auto Count() const -> int { return todo_.Count(); } + private: // Pop any ScopeActions from the top of the stack, propagating results as // needed, to restore the invariant that todo_.Top() is not a ScopeAction. diff --git a/explorer/interpreter/interpreter.cpp b/explorer/interpreter/interpreter.cpp index a17ed744a185..e143c259f22b 100644 --- a/explorer/interpreter/interpreter.cpp +++ b/explorer/interpreter/interpreter.cpp @@ -952,6 +952,10 @@ auto Interpreter::CallFunction(const CallExpression& call, Nonnull fun, Nonnull arg, ImplWitnessMap&& witnesses) -> ErrorOr { + constexpr int StackSizeLimit = 1000; + if (todo_.Count() > StackSizeLimit) { + return ProgramError(call.source_loc()) << "stack overflow"; + } if (trace_stream_->is_enabled()) { *trace_stream_ << "calling function: " << *fun << "\n"; } diff --git a/explorer/testdata/function/fail_recursion_stackoverflow.carbon b/explorer/testdata/function/fail_recursion_stackoverflow.carbon new file mode 100644 index 000000000000..153b9718b8a3 --- /dev/null +++ b/explorer/testdata/function/fail_recursion_stackoverflow.carbon @@ -0,0 +1,20 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// AUTOUPDATE +// RUN: %{not} %{explorer-run} +// RUN: %{not} %{explorer-run-trace} + +package EmptyIdentifier impl; + +fn A() { + // CHECK:STDERR: RUNTIME ERROR: {{.*}}/explorer/testdata/function/fail_recursion_stackoverflow.carbon:[[@LINE+1]]: stack overflow + A(); +} + +fn Main() -> i32 +{ + A(); + return 0; +}