Skip to content
Permalink
Browse files

Prevent panic on flagSet access from custom BashComplete

Fixes #944
  • Loading branch information
unRob committed Nov 25, 2019
1 parent 4805bd1 commit 90a62d7b0c1620a167002eb10a5e2f13924272de
Showing with 51 additions and 3 deletions.
  1. +4 −3 command.go
  2. +47 −0 command_test.go
@@ -100,7 +100,7 @@ func (c *Command) Run(ctx *Context) (err error) {
c.UseShortOptionHandling = true
}

set, err := c.parseFlags(ctx.Args())
set, err := c.parseFlags(ctx.Args(), ctx.shellComplete)

context := NewContext(ctx.App, set, ctx)
context.Command = c
@@ -174,7 +174,7 @@ func (c *Command) useShortOptionHandling() bool {
return c.UseShortOptionHandling
}

func (c *Command) parseFlags(args Args) (*flag.FlagSet, error) {
func (c *Command) parseFlags(args Args, shellComplete bool) (*flag.FlagSet, error) {
set, err := c.newFlagSet()
if err != nil {
return nil, err
@@ -185,7 +185,8 @@ func (c *Command) parseFlags(args Args) (*flag.FlagSet, error) {
}

err = parseIter(set, c, args.Tail())
if err != nil {
// Continue parsing flags on failure during shell completion
if err != nil && !shellComplete {
return nil, err
}

@@ -1,6 +1,7 @@
package cli

import (
"bytes"
"errors"
"flag"
"fmt"
@@ -329,3 +330,49 @@ func TestCommandSkipFlagParsing(t *testing.T) {
expect(t, args, c.expectedArgs)
}
}

func TestCommand_Run_CustomShellCompleteAcceptsMalformedFlags(t *testing.T) {
cases := []struct {
testArgs args
expectedOut string
}{
{testArgs: args{"--undefined"}, expectedOut: "found 0 args"},
{testArgs: args{"--number"}, expectedOut: "found 0 args"},
{testArgs: args{"--number", "fourty-two"}, expectedOut: "found 0 args"},
{testArgs: args{"--number", "42"}, expectedOut: "found 0 args"},
{testArgs: args{"--number", "42", "newArg"}, expectedOut: "found 1 args"},
}

for _, c := range cases {
var outputBuffer bytes.Buffer
app := &App{
Writer: &outputBuffer,
EnableBashCompletion: true,
Commands: []*Command{
{
Name: "bar",
Usage: "this is for testing",
Flags: []Flag{
&IntFlag{
Name: "number",
Usage: "A number to parse",
},
},
BashComplete: func(c *Context) {
fmt.Fprintf(c.App.Writer, "found %d args", c.NArg())
},
},
},
}

osArgs := args{"foo", "bar"}
osArgs = append(osArgs, c.testArgs...)
osArgs = append(osArgs, "--generate-bash-completion")

err := app.Run(osArgs)
stdout := outputBuffer.String()
expect(t, err, nil)
expect(t, stdout, c.expectedOut)
}

}

0 comments on commit 90a62d7

Please sign in to comment.
You can’t perform that action at this time.