AlecAivazis / survey

A golang library for building interactive and accessible prompts with full support for windows and posix terminals.
MIT License
4.07k stars 351 forks source link

Confirm with AskOne panics on command with yes piping #394

Open renta opened 2 years ago

renta commented 2 years ago

What operating system and terminal are you using? Linux

An example that showcases the bug. Simple yes piping lead to a panic for survey.Confirm and survey.AskOne code. I have a cli-command which is asking yes-no on action confirmation. This is the code:

confirm := false
prompt := &survey.Confirm{
    Message: fmt.Sprintf("Do you want to cancel this number %d of events?", eventsNum),
}
if confirmErr := survey.AskOne(prompt, &confirm); confirmErr != nil {
    return fmt.Errorf("error on asking for the confirm: %w", confirmErr)
}
if !confirm {
    return nil
}

It works well with an interactive input when I type yes or no. Bet when I use predefined answer like:

yes | my-fancy-command with --options=value
yes yes | my-fancy-command with --options=value
echo yes | my-fancy-command with --options=value

What did you expect to see? Next execution output of the command.

What did you see instead? I see panic. Top part of the stack:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x7aabea]

goroutine 1 [running]:
github.com/AlecAivazis/survey/v2/terminal.(*RuneReader).ReadLineWithDefault.func2(...)
    /go/pkg/mod/github.com/!alec!aivazis/survey/v2@v2.2.14/terminal/runereader.go:65
github.com/AlecAivazis/survey/v2/terminal.(*RuneReader).ReadLineWithDefault(0xc000292ab0, 0x0, 0x176b1d0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x7f9871d175b8, ...)
    /go/pkg/mod/github.com/!alec!aivazis/survey/v2@v2.2.14/terminal/runereader.go:321 +0xf0a
github.com/AlecAivazis/survey/v2/terminal.(*RuneReader).ReadLine(...)
    /go/pkg/mod/github.com/!alec!aivazis/survey/v2@v2.2.14/terminal/runereader.go:37
github.com/AlecAivazis/survey/v2.(*Confirm).getBool(0xc000168b00, 0x1040d00, 0xc000388888, 0xf64b00, 0x0, 0x0)
    /go/pkg/mod/github.com/!alec!aivazis/survey/v2@v2.2.14/confirm.go:57 +0x191
github.com/AlecAivazis/survey/v2.(*Confirm).Prompt(0xc000168b00, 0xc000388888, 0xc00000e010, 0x112c8f0, 0xc00000e018, 0x1125180)
    /go/pkg/mod/github.com/!alec!aivazis/survey/v2@v2.2.14/confirm.go:136 +0x16d
github.com/AlecAivazis/survey/v2.Ask(0xc0001a5bf0, 0x1, 0x1, 0xe6fde0, 0xc00039844a, 0x0, 0x0, 0x0, 0x0, 0x0)
    /go/pkg/mod/github.com/!alec!aivazis/survey/v2@v2.2.14/survey.go:306 +0x57b
github.com/AlecAivazis/survey/v2.AskOne(...)
    /go/pkg/mod/github.com/!alec!aivazis/survey/v2@v2.2.14/survey.go:249
main.glob..func1(0x172f260, 0xc0003d21e0, 0x0, 0x1, 0x0, 0x0)
mislav commented 2 years ago

Thank you for reporting. Survey was not designed to take input from a stream that's not connected to a terminal, but I agree that we should avoid a panic and instead throw a more informative error message. Better yet, maybe Survey could work with any standard input stream, even if it's not a terminal.

To avoid this in your app for now, you should check whether os.Stdin is a terminal, and avoid invoking Survey otherwise.

gunta commented 1 year ago

+1

Getting the same error when running a command that uses survey, running from the shell of http://github.com/google/zx

Zx is not a real terminal