From f6a4ccdc8387b13f5caca8dc2251b785812bc672 Mon Sep 17 00:00:00 2001 From: John Ferlan Date: Mon, 10 Oct 2016 09:01:18 -0400 Subject: [PATCH] vsh: Fix some issues in auto completion code 1. Move the declaration of const vshCmdDef *help - it should be at the top of the "if" rather than in the middle. 2. Change a comparison from && to || - without doing so we could crash on commands like 'virsh list' which would allow completion of some non -- option based on whatever was found in the current working directory and then as soon as that was completed, the next would crash since "opt" would be returned as NULL, but the check was dereferencing "&& opt->type" 3. Before dereferencing opt->completer, be sure opt isn't NULL. --- tools/vsh.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/vsh.c b/tools/vsh.c index 420eb7931f..9558dadb63 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -1523,10 +1523,11 @@ vshCommandParse(vshControl *ctl, vshCommandParser *parser) /* if we encountered --help, replace parsed command with * 'help ' */ for (tmpopt = first; tmpopt; tmpopt = tmpopt->next) { + const vshCmdDef *help; if (STRNEQ(tmpopt->def->name, "help")) continue; - const vshCmdDef *help = vshCmddefSearch("help"); + help = vshCmddefSearch("help"); vshCommandOptFree(first); first = vshMalloc(ctl, sizeof(vshCmdOpt)); first->def = help->opts; @@ -2788,7 +2789,7 @@ vshReadlineParse(const char *text, int state) * Try to find the default option. */ if (!(opt = vshCmddefGetData(cmd, &opts_need_arg, &opts_seen)) - && opt->type == VSH_OT_BOOL) + || opt->type == VSH_OT_BOOL) goto error; opt_exists = true; opts_need_arg = const_opts_need_arg; @@ -2824,7 +2825,7 @@ vshReadlineParse(const char *text, int state) res = vshReadlineCommandGenerator(sanitized_text, state); } else if (opts_filled && !non_bool_opt_exists) { res = vshReadlineOptionsGenerator(sanitized_text, state, cmd); - } else if (non_bool_opt_exists && data_complete && opt->completer) { + } else if (non_bool_opt_exists && data_complete && opt && opt->completer) { if (!completed_list) completed_list = opt->completer(autoCompleteOpaque, opt->completer_flags);