mirror of
https://github.com/nushell/nushell.git
synced 2025-07-02 23:51:49 +02:00
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:
committed by
GitHub
parent
9bc4e6794d
commit
00469de93e
@ -351,6 +351,41 @@ pub fn parse_def(
|
||||
*declaration = signature.clone().into_block_command(block_id);
|
||||
|
||||
let mut block = working_set.get_block_mut(block_id);
|
||||
let calls_itself = block.pipelines.iter().any(|pipeline| {
|
||||
pipeline
|
||||
.elements
|
||||
.iter()
|
||||
.any(|pipe_element| match pipe_element {
|
||||
PipelineElement::Expression(
|
||||
_,
|
||||
Expression {
|
||||
expr: Expr::Call(call_expr),
|
||||
..
|
||||
},
|
||||
) => {
|
||||
if call_expr.decl_id == decl_id {
|
||||
return true;
|
||||
}
|
||||
call_expr.arguments.iter().any(|arg| match arg {
|
||||
Argument::Positional(Expression { expr, .. }) => match expr {
|
||||
Expr::Keyword(.., expr) => {
|
||||
let expr = expr.as_ref();
|
||||
let Expression { expr, .. } = expr;
|
||||
match expr {
|
||||
Expr::Call(call_expr2) => call_expr2.decl_id == decl_id,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
Expr::Call(call_expr2) => call_expr2.decl_id == decl_id,
|
||||
_ => false,
|
||||
},
|
||||
_ => false,
|
||||
})
|
||||
}
|
||||
_ => false,
|
||||
})
|
||||
});
|
||||
block.recursive = Some(calls_itself);
|
||||
block.signature = signature;
|
||||
block.redirect_env = def_call == b"def-env";
|
||||
} else {
|
||||
|
Reference in New Issue
Block a user