Skip to content

fix(interpreter): split command substitution output on IFS in list context#374

Merged
chaliy merged 2 commits intomainfrom
claude/fix-347-word-splitting-Vvs93
Feb 27, 2026
Merged

fix(interpreter): split command substitution output on IFS in list context#374
chaliy merged 2 commits intomainfrom
claude/fix-347-word-splitting-Vvs93

Conversation

@chaliy
Copy link
Contributor

@chaliy chaliy commented Feb 27, 2026

Summary

  • Fix word splitting for unquoted $() command substitution in list contexts (e.g., for x in $(cmd))
  • Previously, the entire command substitution output was treated as a single token; now it is split on IFS characters (space/tab/newline by default)
  • Add 3 spec tests covering for-loop with find, space-separated words, and newline-separated output

Details

The root cause was in expand_word_to_fields() in crates/bashkit/src/interpreter/mod.rs. For words that weren't array expansions, it called expand_word() which returns a single concatenated string, then wrapped it in a single-element vec. There was no IFS-based field splitting step for unquoted command substitutions.

The fix checks if the word is unquoted and contains a CommandSubstitution part. If so, the expanded result is split on IFS characters (defaulting to space/tab/newline), with consecutive whitespace collapsed and empty results elided. This matches POSIX shell semantics and real bash behavior.

Test plan

  • Added 3 new spec tests in command-subst.test.sh (for-loop splitting, space splitting, newline splitting)
  • All 1308 bash spec tests pass (1184 passed + 124 skipped, 0 failed)
  • 1084/1084 bash comparison tests match real bash (100%)
  • cargo fmt --check clean
  • cargo clippy --all-targets --all-features -- -D warnings clean
  • Unit tests and threat model tests pass

Closes #347

@chaliy chaliy force-pushed the claude/fix-347-word-splitting-Vvs93 branch from 5c28718 to b378a79 Compare February 27, 2026 23:14
…ntext

Unquoted $() results in for-loop word lists (and other list contexts)
were treated as a single token. Now expand_word_to_fields performs
IFS-based field splitting when the word is unquoted and contains a
CommandSubstitution part, matching POSIX/bash semantics.

Added spec tests: for-loop with find, space-separated words, newlines.

Closes #347
Replace filesystem-dependent find command with printf to avoid
VFS vs real filesystem mismatch in CI comparison tests. The test
still validates word-splitting of command substitution output in
for-loop list context.
@chaliy chaliy force-pushed the claude/fix-347-word-splitting-Vvs93 branch from b378a79 to 01ffa67 Compare February 27, 2026 23:25
@chaliy chaliy merged commit e1334ef into main Feb 27, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: word splitting on $() command substitution broken in for-loops

2 participants