mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-21 19:02:25 +00:00
vshReadlineParse: Escape list of candidates earlier
The way our completer callbacks work is that they return all possible candidates and then vshCompleterFilter() is called to prune the list of all candidates removing those which don't match user's input. This allows us to have simpler completer callbacks as their only job is to fetch all possible candidates. Anyway, if the completion candidate we're returning contains a space, it has to be escaped (shell like escaping), unless there is already a quote character (single quote or double quote). But ordering is critical. Completer callback returns string without any escaping, but the filter function sees the user input escaped. For instance, if user's input is "domain with space<TAB>" then the filtering function gets "domain\ with\ space" as user's input but completer returns "domain with space". Since these two strings don't match the filtering function removes this candidate from the list. What we need to do is to escape strings before calling the filtering function. This way, the filtering function will see two same strings. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
c31e80c653
commit
f61a4e91ef
26
tools/vsh.c
26
tools/vsh.c
@ -2751,10 +2751,26 @@ vshReadlineParse(const char *text, int state)
|
||||
partial,
|
||||
opt->completer_flags);
|
||||
|
||||
/* Escape completions, if needed (i.e. argument
|
||||
* we are completing wasn't started with a quote
|
||||
* character). This also enables filtering done
|
||||
* below to work properly. */
|
||||
if (completer_list &&
|
||||
!rl_completion_quote_character) {
|
||||
size_t i;
|
||||
|
||||
for (i = 0; completer_list[i]; i++) {
|
||||
g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
|
||||
|
||||
virBufferEscape(&buf, '\\', " ", "%s", completer_list[i]);
|
||||
VIR_FREE(completer_list[i]);
|
||||
completer_list[i] = virBufferContentAndReset(&buf);
|
||||
}
|
||||
}
|
||||
|
||||
/* For string list returned by completer we have to do
|
||||
* filtering based on @text because completer returns all
|
||||
* possible strings. */
|
||||
|
||||
if (completer_list &&
|
||||
(vshCompleterFilter(&completer_list, text) < 0 ||
|
||||
virStringListMerge(&list, &completer_list) < 0)) {
|
||||
@ -2770,14 +2786,6 @@ vshReadlineParse(const char *text, int state)
|
||||
list_index++;
|
||||
}
|
||||
|
||||
if (ret &&
|
||||
!rl_completion_quote_character) {
|
||||
g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
|
||||
virBufferEscape(&buf, '\\', " ", "%s", ret);
|
||||
VIR_FREE(ret);
|
||||
ret = virBufferContentAndReset(&buf);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (!ret) {
|
||||
g_strfreev(list);
|
||||
|
Loading…
x
Reference in New Issue
Block a user