Limit recursion to avoid stack overflow (#7657)

Add recursion limit to `def` and `block`.
Summary of this PR , it will detect if `def` call itself or not .
Then execute by using `stack` which I think best choice to use with this
design and core as it is available in all crates and mutable and
calculate the recursion limit on calling `def`.
Set 50 as recursion limit on `Config`.
Add some tests too .

Fixes #5899

Co-authored-by: Reilly Wood <reilly.wood@icloud.com>
This commit is contained in:
Amirhossein Akhlaghpour
2023-01-04 21:38:50 -05:00
committed by GitHub
parent 9bc4e6794d
commit 00469de93e
6 changed files with 85 additions and 0 deletions

View File

@ -145,3 +145,18 @@ fn override_table_eval_file() {
let actual = nu!(cwd: ".", r#"def table [] { "hi" }; table"#);
assert_eq!(actual.out, "hi");
}
// This test is disabled on Windows because they cause a stack overflow in CI (but not locally!).
// For reasons we don't understand, the Windows CI runners are prone to stack overflow.
// TODO: investigate so we can enable on Windows
#[cfg(not(target_os = "windows"))]
#[test]
fn infinite_recursion_does_not_panic() {
let actual = nu!(
cwd: ".",
r#"
def bang [] { bang }; bang
"#
);
assert!(actual.err.contains("Recursion limit (50) reached"));
}