From: John Ferlan Date: Mon, 10 Oct 2016 13:01:18 +0000 (-0400) Subject: vsh: Fix some issues in auto completion code X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=f6a4ccdc8387b13f5caca8dc2251b785812bc672;p=libvirt.git 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. --- 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);