]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
vshReadlineParse: Escape returned results if needed
authorMichal Privoznik <mprivozn@redhat.com>
Mon, 13 Nov 2017 12:34:54 +0000 (13:34 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Thu, 11 Jan 2018 17:53:04 +0000 (18:53 +0100)
When returning a string that needs escaping there are two
scenarios that can happen. Firstly, user already started the
string with a quote (or double quote) in which case we don't need
to do anything - readline takes care of that. However, if they
haven't typed anything yet, we need to escape the string
ourselves.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
tools/vsh.c

index 3c93e94d8da61b5872c748f54e666a8480f46002..e179a0407015cf9e83c06eccb26cf405a6c910fa 100644 (file)
@@ -2735,6 +2735,14 @@ vshReadlineParse(const char *text, int state)
         res = vshReadlineOptionsGenerator(text, state, cmd);
     }
 
+    if (res &&
+        !rl_completion_quote_character) {
+        virBuffer buf = VIR_BUFFER_INITIALIZER;
+        virBufferEscapeShell(&buf, res);
+        VIR_FREE(res);
+        res = virBufferContentAndReset(&buf);
+    }
+
     if (!res) {
         vshCommandFree(partial);
         partial = NULL;
@@ -2754,6 +2762,16 @@ vshReadlineCompletion(const char *text,
     return matches;
 }
 
+
+static int
+vshReadlineCharIsQuoted(char *line, int idx)
+{
+    return idx > 0 &&
+           line[idx - 1] == '\\' &&
+           !vshReadlineCharIsQuoted(line, idx - 1);
+}
+
+
 # define HISTSIZE_MAX 500000
 
 static int
@@ -2765,6 +2783,7 @@ vshReadlineInit(vshControl *ctl)
     char *histsize_env = NULL;
     const char *histsize_str = NULL;
     const char *break_characters = " \t\n\\`@$><=;|&{(";
+    const char *quote_characters = "\"'";
 
     /* Opaque data for autocomplete callbacks. */
     autoCompleteOpaque = ctl;
@@ -2788,6 +2807,14 @@ vshReadlineInit(vshControl *ctl)
     rl_basic_word_break_characters = (char *) break_characters;
 # endif
 
+# if defined(RL_READLINE_VERSION) && RL_READLINE_VERSION > 0x0402
+    rl_completer_quote_characters = quote_characters;
+    rl_char_is_quoted_p = vshReadlineCharIsQuoted;
+# else
+    rl_completer_quote_characters = (char *) quote_characters;
+    rl_char_is_quoted_p = (Function *) vshReadlineCharIsQuoted;
+# endif
+
     if (virAsprintf(&histsize_env, "%s_HISTSIZE", ctl->env_prefix) < 0)
         goto cleanup;