[PATCH 6/9] vshReadlineParse: Escape list of candidates earlier
Ján Tomko
jtomko at redhat.com
Tue Jan 26 15:29:49 UTC 2021
On a Tuesday in 2021, Michal Privoznik wrote:
>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 at redhat.com>
>---
> tools/vsh.c | 26 +++++++++++++++++---------
> 1 file changed, 17 insertions(+), 9 deletions(-)
>
>diff --git a/tools/vsh.c b/tools/vsh.c
>index abbd323e24..27c201389d 100644
>--- a/tools/vsh.c
>+++ b/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 completing wasn't started with a quote
we are completing
Jano
>+ * 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)) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 484 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20210126/f04e468f/attachment-0001.sig>
More information about the libvir-list
mailing list