Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions docs/spec/reference/arg.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,32 @@ arg "<file>" var=#true # multiple args can be passed (e.g. mycli file1 file2 fil
arg "<file>..." # shorthand for var=#true (trailing ellipsis)
arg "<file>" var=#true var_min=3 # at least 3 args must be passed
arg "<file>" var=#true var_max=3 # up to 3 args can be passed
```

## Using Variadic Args in Bash

When using variadic arguments (`var=#true`), the values are passed as a shell-escaped
string via the `usage_<name>` environment variable. To properly handle arguments
containing spaces as a bash array, wrap the variable in parentheses:

```bash
# Given: usage_files="arg1 'arg with space' arg3"

# Convert to bash array:
eval "files=($usage_files)"

Copilot AI Jan 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using eval with user-controlled input can introduce command injection vulnerabilities. If usage_files contains malicious shell commands, they will be executed. Consider documenting safer alternatives such as using readarray with process substitution, or add prominent security warnings about input validation if eval is necessary.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

The use of eval here is vulnerable to globbing. If a user provides an argument like *, it will be expanded to a list of all files in the current directory, which can lead to unexpected behavior and security risks. To make this example safer for users to copy and paste, it's crucial to disable globbing before the eval command and restore it afterward.

Suggested change
eval "files=($usage_files)"
set -f # Disable globbing to prevent filename expansion
eval "files=($usage_files)"
set +f # Re-enable globbing
References
  1. When using eval to parse a string into shell arguments, it's important to disable globbing (set -f) to prevent unintended filename expansion from characters like * and ? in the input string. This is a common security best practice for writing robust shell scripts.


# Now use as array:
for f in "${files[@]}"; do
echo "Processing: $f"
done

# Or pass to commands:
touch "${files[@]}"
```

This pattern ensures arguments with spaces are handled correctly as separate elements.

```kdl
arg "<shell>" {
choices "bash" "zsh" "fish" # <shell> must be one of the choices
}
Expand Down