Prevent infinite recursion when completion wraps variable assignment

Closes #7344

Apply a targeted fix to the place where complete() is called to handle nested
variable assignments.  Sadly, reporting an error is probably not okay here,
because people might legitimately use aliases like:

	alias vim "A=B command vim"

This is all a bit ugly, and I hope to find a cleaner solution.  Supporting
completions on commandlines like `x=$PWD cd $x/ ` is a nice feature but it
comes with some complexity.
This commit is contained in:
Johannes Altmanninger 2020-09-22 00:55:28 +02:00
parent ca538fa8d8
commit 0a0149cc2a
2 changed files with 12 additions and 2 deletions

View file

@ -1600,8 +1600,14 @@ void completer_t::perform() {
ctx.parser->libdata().transient_commandlines.push_back(unaliased_cmd);
cleanup_t remove_transient(
[&] { ctx.parser->libdata().transient_commandlines.pop_back(); });
vec_append(this->completions,
complete(unaliased_cmd, completion_request_t::fuzzy_match, ctx));
// Prevent infinite recursion when the completion for x wraps "A=B x" (#7344).
// Don't report an error since this could be a legitimate alias.
static uint32_t complete_assignment_recursion_count;
if (complete_assignment_recursion_count++ < 24) {
vec_append(this->completions,
complete(unaliased_cmd, completion_request_t::fuzzy_match, ctx));
}
complete_assignment_recursion_count--;
do_file = false;
} else if (!complete_param(
cmd, previous_argument_unescape, current_argument_unescape,

View file

@ -26,3 +26,7 @@ complete -c testcommand2 --wraps "testcommand2 from_wraps "
complete -C'testcommand2 explicit '
# CHECKERR: explicit
# CHECKERR: from_wraps explicit
complete -c recvar --wraps 'A=B recvar'
complete -C 'recvar '