1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-28 10:25:10 +00:00

Shell: Make for/match/functions put their variables only in the new scope

Otherwise, a function would, for example, overwrite its parent scope:
```sh
foo(x) { }
x=1
foo 2 # would make x=2 otherwise
```
This commit is contained in:
AnotherTest 2020-12-09 15:34:55 +03:30 committed by Andreas Kling
parent 97c5a78d27
commit 9bd81f34a5
3 changed files with 9 additions and 4 deletions

View file

@ -1034,7 +1034,7 @@ RefPtr<Value> ForLoop::run(RefPtr<Shell> shell)
{
auto frame = shell->push_frame(String::formatted("for ({})", this));
shell->set_local_variable(m_variable_name, value);
shell->set_local_variable(m_variable_name, value, true);
block_value = m_block->run(shell);
}
@ -1587,7 +1587,7 @@ RefPtr<Value> MatchExpr::run(RefPtr<Shell> shell)
auto frame = shell->push_frame(String::formatted("match ({})", this));
if (!m_expr_name.is_empty())
shell->set_local_variable(m_expr_name, value);
shell->set_local_variable(m_expr_name, value, true);
for (auto& entry : m_entries) {
for (auto& option : entry.options) {
@ -1598,7 +1598,7 @@ RefPtr<Value> MatchExpr::run(RefPtr<Shell> shell)
size_t i = 0;
for (auto& name : entry.match_names.value()) {
if (spans.size() > i)
shell->set_local_variable(name, create<AST::StringValue>(spans[i]));
shell->set_local_variable(name, create<AST::StringValue>(spans[i]), true);
++i;
}
}

View file

@ -479,7 +479,7 @@ bool Shell::invoke_function(const AST::Command& command, int& retval)
size_t index = 0;
for (auto& arg : function.arguments) {
++index;
set_local_variable(arg, adopt(*new AST::StringValue(command.argv[index])));
set_local_variable(arg, adopt(*new AST::StringValue(command.argv[index])), true);
}
auto argv = command.argv;

View file

@ -34,3 +34,8 @@ fn() {
fn2() { }
test "$(fn foobar)" = "foobar" || echo 'Frames are somehow messed up in nested functions' && exit 1
fn(xfoo) { }
xfoo=1
fn 2
test $xfoo -eq 1 || echo 'Functions overwrite parent scopes' && exit 1