mirror of
https://github.com/nushell/nushell.git
synced 2025-06-30 22:50:14 +02:00
Avoid panic when pipe a variable to a custom command which have recursive call (#12491)
# Description Fixes: #11351 And comment here is also fixed: https://github.com/nushell/nushell/issues/11351#issuecomment-1996191537 The panic can happened if we pipe a variable to a custom command which recursively called itself inside another block. TBH, I think I figure out how it works to panic, but I'm not sure if there is a potention issue if nushell don't mutate a block in such case. # User-Facing Changes Nan # Tests + Formatting Done # After Submitting Done --------- Co-authored-by: Stefan Holderbach <sholderbach@users.noreply.github.com>
This commit is contained in:
@ -6289,7 +6289,19 @@ pub fn parse(
|
||||
// panic (again, in theory, this shouldn't be possible)
|
||||
let block = working_set.get_block(block_id);
|
||||
let block_captures_empty = block.captures.is_empty();
|
||||
if !captures.is_empty() && block_captures_empty {
|
||||
// need to check block_id >= working_set.permanent_state.num_blocks()
|
||||
// to avoid mutate a block that is in the permanent state.
|
||||
// this can happened if user defines a function with recursive call
|
||||
// and pipe a variable to the command, e.g:
|
||||
// def px [] { if true { 42 } else { px } }; # the block px is saved in permanent state.
|
||||
// let x = 3
|
||||
// $x | px
|
||||
// If we don't guard for `block_id`, it will change captures of `px`, which is
|
||||
// already saved in permanent state
|
||||
if !captures.is_empty()
|
||||
&& block_captures_empty
|
||||
&& block_id >= working_set.permanent_state.num_blocks()
|
||||
{
|
||||
let block = working_set.get_block_mut(block_id);
|
||||
block.captures = captures.into_iter().map(|(var_id, _)| var_id).collect();
|
||||
}
|
||||
|
Reference in New Issue
Block a user