Skip to content

Fix syntax error in alias completion when alias contains a single quote - #2407

Open
Saadanjum0 wants to merge 1 commit into
Bash-it:masterfrom
Saadanjum0:fix/alias-completion-quoting
Open

Saadanjum0 wants to merge 1 commit into
Bash-it:masterfrom
Saadanjum0:fix/alias-completion-quoting

Conversation

@Saadanjum0

Copy link
Copy Markdown

What

aliases.completion.bash builds a wrapper completion function for each alias by splicing the alias' command and arguments directly into the generated source as unquoted text, e.g.:

prec_word='$alias_cmd $alias_args'
...
COMP_LINE=${COMP_LINE/$alias_name/$alias_cmd $alias_args}

If the aliased command contains a single quote, this produces invalid (or in some cases silently wrong) generated code. For example:

alias foo="echo it's broken"

generates a snippet with an odd number of unescaped quotes, so sourcing it fails with something like:

bash: /tmp/alias_completion-XXXXXXXXXXX: line NN: unexpected EOF while looking for matching `''

which breaks the user's whole shell startup. This matches #2254, where a maintainer-adjacent contributor traced the problem to this same unquoted interpolation and confirmed it's still present on master.

Fix

Run alias_cmd and alias_args through printf %q before embedding them in the generated wrapper, the same way the existing code already does for alias_arg_words. This keeps the generated source valid regardless of what characters the aliased command/arguments contain.

Notes

  • Behavior change: COMP_LINE used to be rebuilt by splicing in the raw alias text, so any $VAR in the alias got expanded (e.g. alias g2='cap -x "$HOME"' would show the expanded path in COMP_LINE); after this fix COMP_LINE keeps the literal, unexpanded alias text instead, which is arguably more correct but is a real behavior change worth flagging.
  • Known remaining limitation (not a blocker): the while read line loop over alias -p output doesn't use -r, so '\'' sequences from some alias forms still get mangled into '''; completion still loads without crashing, but the resulting words aren't always exactly right. Could be a follow-up.

Testing

Added a regression test (test/completion/aliases.completion.bats) with an alias whose arguments contain a single quote, registering a completion trigger for the aliased command so the test actually exercises the vulnerable code path. Confirmed it fails with a syntax error on the old code (not necessarily the exact EOF message quoted above -- the specific error can vary) and passes with the fix. Ran the full completion and aliases test suites locally (63 tests, all passing).

aliases.completion.bash builds a wrapper completion function for each
alias by splicing the alias' command and arguments directly into the
generated source as unquoted text (e.g. prec_word='$alias_cmd
$alias_args' and the COMP_LINE replacement). If the aliased command
contains a single quote -- for example `alias foo="echo it's broken"`
-- the generated file ends up with an odd number of unescaped quotes,
and sourcing it fails with "unexpected EOF while looking for matching
`''" (or a similar syntax error), breaking the user's whole shell
startup (see Bash-it#2254).

Run alias_cmd and alias_args through printf %q before embedding them,
the same way the existing code already does for alias_arg_words, so
arbitrary characters in the aliased command/arguments can't corrupt
the generated wrapper.

Added a regression test with an alias whose arguments contain a
single quote.

@seefood seefood left a comment

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.

excellent catch! LGTM.

@akinomyoga want to have a look at well?

This branch has not been deployed

No deployments
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.

2 participants