Skip to content

Commit e770ddd

Browse files
vingarzangopherbot
authored andcommitted
x/term: disabling auto-completion around GetPassword()
Triggering the completion during password input might cause some unintended behavior around handling of TAB, or maybe the auto-completion functionality would review the secret input. Hence simply disabling/re-enabling it around the t.readLine call. Fixes #72736 Change-Id: I64270e8570086247247466afb2536b2581d6af25 Reviewed-on: https://go-review.googlesource.com/c/term/+/607115 Reviewed-by: David Chase <[email protected]> Reviewed-by: Keith Randall <[email protected]> Auto-Submit: Sean Liao <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent 04218fd commit e770ddd

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

Diff for: terminal.go

+9
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ type Terminal struct {
4444
// bytes, as an index into |line|). If it returns ok=false, the key
4545
// press is processed normally. Otherwise it returns a replacement line
4646
// and the new cursor position.
47+
//
48+
// This will be disabled during ReadPassword.
4749
AutoCompleteCallback func(line string, pos int, key rune) (newLine string, newPos int, ok bool)
4850

4951
// Escape contains a pointer to the escape codes for this terminal.
@@ -692,13 +694,20 @@ func (t *Terminal) Write(buf []byte) (n int, err error) {
692694

693695
// ReadPassword temporarily changes the prompt and reads a password, without
694696
// echo, from the terminal.
697+
//
698+
// The AutoCompleteCallback is disabled during this call.
695699
func (t *Terminal) ReadPassword(prompt string) (line string, err error) {
696700
t.lock.Lock()
697701
defer t.lock.Unlock()
698702

699703
oldPrompt := t.prompt
700704
t.prompt = []rune(prompt)
701705
t.echo = false
706+
oldAutoCompleteCallback := t.AutoCompleteCallback
707+
t.AutoCompleteCallback = nil
708+
defer func() {
709+
t.AutoCompleteCallback = oldAutoCompleteCallback
710+
}()
702711

703712
line, err = t.readLine()
704713

Diff for: terminal_test.go

+26
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,32 @@ func TestReadPasswordLineEnd(t *testing.T) {
396396
}
397397
}
398398

399+
func MockAutoCompleteCallback(line string, pos int, key rune) (newLine string, newPos int, ok bool) {
400+
return "not-good", pos, true
401+
}
402+
403+
func TestReadPasswordDisabledAutoCompleteCallback(t *testing.T) {
404+
input := "testgood\ranother line\r"
405+
expectedPassword := "testgood"
406+
terminal := NewTerminal(
407+
&MockTerminal{
408+
toSend: []byte(input),
409+
bytesPerRead: 1,
410+
},
411+
"prompt")
412+
terminal.AutoCompleteCallback = MockAutoCompleteCallback
413+
password, err := terminal.ReadPassword("Password: ")
414+
if err != nil {
415+
t.Fatalf("failed to read password: %v", err)
416+
}
417+
if password != expectedPassword {
418+
t.Fatalf("failed to read password, got %q", password)
419+
}
420+
if terminal.AutoCompleteCallback == nil {
421+
t.Fatalf("AutoCompleteCallback should not be nil after ReadPassword")
422+
}
423+
}
424+
399425
func TestMakeRawState(t *testing.T) {
400426
fd := int(os.Stdout.Fd())
401427
if !IsTerminal(fd) {

0 commit comments

Comments
 (0)