Skip to content

Commit

Permalink
Return an error when the terminal reports zero columns and is refreshed
Browse files Browse the repository at this point in the history
When used within a call to `docker exec -it` where the original
container does not have a TTY allocated to it (such as in
moby/moby#8755), the number of columns read from the `ioctl()` call
will be zero, but it will not return an error. If you call `Prompt()` or
`PasswordPrompt()` after this, the prompt will panic when it tries to
divide a number by the number of columns (which is zero).

This change detects when the number of columns returned is zero and
returns `ErrNoColumns` from the `PromptXXX` methods to avoid a panic and
so the application is able to deal with the problem more easily.
  • Loading branch information
jsternberg committed Feb 13, 2017
1 parent bf27d3b commit ee08c9f
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 1 deletion.
4 changes: 4 additions & 0 deletions common.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ var ErrNotTerminalOutput = errors.New("standard output is not a terminal")
// be colour codes on some platforms).
var ErrInvalidPrompt = errors.New("invalid prompt")

// ErrNoColumns is returned when a prompt is unable to be refreshed because the
// number of columns read from the ioctl() call is zero.
var ErrNoColumns = errors.New("no columns for prompt")

// KillRingMax is the max number of elements to save on the killring.
const KillRingMax = 60

Expand Down
8 changes: 7 additions & 1 deletion line.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ const (
)

func (s *State) refresh(prompt []rune, buf []rune, pos int) error {
if s.columns == 0 {
return ErrNoColumns
}

s.needRefresh = false
if s.multiLineMode {
return s.refreshMultiLine(prompt, buf, pos)
Expand Down Expand Up @@ -624,7 +628,9 @@ mainLoop:
switch v {
case cr, lf:
if s.needRefresh {
s.refresh(p, line, pos)
if err := s.refresh(p, line, pos); err != nil {
return "", err
}
}
if s.multiLineMode {
s.resetMultiLine(p, line, pos)
Expand Down

0 comments on commit ee08c9f

Please sign in to comment.