diff options
author | AnotherTest <ali.mpfard@gmail.com> | 2020-12-09 15:34:55 +0330 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-12-29 16:55:43 +0100 |
commit | 9bd81f34a522b1d5e48e1f1e8c308a2ac38f415d (patch) | |
tree | 9be94da11cd36ff937cc1e51c9f389bbc9d6861a | |
parent | 97c5a78d27e9dddc12e6b20430892d11016cb6dd (diff) | |
download | serenity-9bd81f34a522b1d5e48e1f1e8c308a2ac38f415d.zip |
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
```
-rw-r--r-- | Shell/AST.cpp | 6 | ||||
-rw-r--r-- | Shell/Shell.cpp | 2 | ||||
-rw-r--r-- | Shell/Tests/function.sh | 5 |
3 files changed, 9 insertions, 4 deletions
diff --git a/Shell/AST.cpp b/Shell/AST.cpp index 2de6c75cbd..a0350fa755 100644 --- a/Shell/AST.cpp +++ b/Shell/AST.cpp @@ -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; } } diff --git a/Shell/Shell.cpp b/Shell/Shell.cpp index 605b27bcf3..9f079a8004 100644 --- a/Shell/Shell.cpp +++ b/Shell/Shell.cpp @@ -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; diff --git a/Shell/Tests/function.sh b/Shell/Tests/function.sh index f3ef5aaeed..b9c23308ea 100644 --- a/Shell/Tests/function.sh +++ b/Shell/Tests/function.sh @@ -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 |