From eb5ce0bd0ed1af905703131c77ab0b1d68c0f1ef Mon Sep 17 00:00:00 2001 From: Mykhailo Chalyi Date: Fri, 3 Apr 2026 12:07:08 +0000 Subject: [PATCH] fix(interpreter): remove exported vars from env on unset unset VAR removed the variable from self.variables but not self.env. Since variable lookup falls back to self.env, unset exported variables remained accessible. Now self.env.remove() is called alongside self.variables.remove(). Closes #946 --- crates/bashkit/src/interpreter/mod.rs | 1 + .../bash/unset-exported-var.test.sh | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 crates/bashkit/tests/spec_cases/bash/unset-exported-var.test.sh diff --git a/crates/bashkit/src/interpreter/mod.rs b/crates/bashkit/src/interpreter/mod.rs index d393bc04..b81e408b 100644 --- a/crates/bashkit/src/interpreter/mod.rs +++ b/crates/bashkit/src/interpreter/mod.rs @@ -4794,6 +4794,7 @@ impl Interpreter { continue; } self.variables.remove(&resolved); + self.env.remove(&resolved); self.arrays.remove(&resolved); self.assoc_arrays.remove(&resolved); for frame in self.call_stack.iter_mut().rev() { diff --git a/crates/bashkit/tests/spec_cases/bash/unset-exported-var.test.sh b/crates/bashkit/tests/spec_cases/bash/unset-exported-var.test.sh new file mode 100644 index 00000000..5c1a484d --- /dev/null +++ b/crates/bashkit/tests/spec_cases/bash/unset-exported-var.test.sh @@ -0,0 +1,27 @@ +### unset_exported_variable +# unset should remove exported vars completely +export UNSET_TEST=value +unset UNSET_TEST +echo "${UNSET_TEST:-gone}" +### expect +gone +### end + +### unset_then_check_defined +### skip: [[ -v VAR ]] unary operator not yet implemented +# unset var should not be -v defined +export UNSET_DEF_TEST=x +unset UNSET_DEF_TEST +[[ -v UNSET_DEF_TEST ]] && echo "still set" || echo "unset" +### expect +unset +### end + +### unset_regular_variable +# unset non-exported var (verify no regression) +REGULAR=hello +unset REGULAR +echo "${REGULAR:-gone}" +### expect +gone +### end