Skip to content

Commit 17abfba

Browse files
authored
fix(interpreter): get_ifs_separator respects local IFS (#902)
## Summary - `get_ifs_separator()` only checked `self.variables` for IFS, missing local IFS declarations stored in `call_stack.locals`. This caused `local IFS=":"` to have no effect on `"${arr[*]}"` array joining inside functions. - Fix: use `expand_variable("IFS")` which checks locals first, with proper handling of unset vs empty IFS. - Includes regression test. ## Test plan - [x] `cargo test --all-features -p bashkit --lib` — all 2123 tests pass - [x] `cargo clippy --all-targets --all-features -- -D warnings` — clean - [x] `cargo fmt --check` — clean - [x] Regression test `test_local_ifs_array_join` covers the exact bug
1 parent 9ba8460 commit 17abfba

File tree

3 files changed

+29
-6
lines changed

3 files changed

+29
-6
lines changed

crates/bashkit/src/interpreter/mod.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7980,13 +7980,16 @@ impl Interpreter {
79807980

79817981
/// Get the separator for `[*]` array joins: first char of IFS, or space if IFS unset.
79827982
fn get_ifs_separator(&self) -> String {
7983-
match self.variables.get("IFS") {
7984-
Some(ifs) => ifs
7985-
.chars()
7983+
let ifs = self.expand_variable("IFS");
7984+
if ifs.is_empty() && !self.is_variable_set("IFS") {
7985+
// IFS unset: default separator is space
7986+
" ".to_string()
7987+
} else {
7988+
// IFS set (possibly empty): first char or empty
7989+
ifs.chars()
79867990
.next()
79877991
.map(|c| c.to_string())
7988-
.unwrap_or_default(),
7989-
None => " ".to_string(),
7992+
.unwrap_or_default()
79907993
}
79917994
}
79927995

crates/bashkit/src/lib.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2485,6 +2485,26 @@ fn
24852485
assert_eq!(result.stdout, "test\n");
24862486
}
24872487

2488+
#[tokio::test]
2489+
async fn test_local_ifs_array_join() {
2490+
// Regression: local IFS=":" must affect "${arr[*]}" joining
2491+
let mut bash = Bash::new();
2492+
let result = bash
2493+
.exec(
2494+
r#"
2495+
fn() {
2496+
local arr=(a b c)
2497+
local IFS=":"
2498+
echo "${arr[*]}"
2499+
}
2500+
fn
2501+
"#,
2502+
)
2503+
.await
2504+
.unwrap();
2505+
assert_eq!(result.stdout, "a:b:c\n");
2506+
}
2507+
24882508
#[tokio::test]
24892509
async fn test_glob_star() {
24902510
let mut bash = Bash::new();

supply-chain/config.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,7 @@ version = "2.13.0"
575575
criteria = "safe-to-deploy"
576576

577577
[[exemptions.insta]]
578-
version = "1.47.1"
578+
version = "1.47.2"
579579
criteria = "safe-to-run"
580580

581581
[[exemptions.instant]]

0 commit comments

Comments
 (0)