From e327b30f420dd77ac32d74e81b7db5a765b0fdf6 Mon Sep 17 00:00:00 2001 From: John Schnake Date: Wed, 6 Apr 2016 11:11:13 -0500 Subject: [PATCH] x/crypto/ssh/terminal: ensure windows MakeRaw returns previous state The MakeRaw method should be returning the original state so that it can be restored. However, the current implementation is returning the new, "raw" state. Fixes golang/go#15155 Change-Id: I8e0b87229b7577544e1118fa4b95664d3a9cf5da Reviewed-on: https://go-review.googlesource.com/21612 Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- ssh/terminal/terminal_test.go | 22 ++++++++++++++++++++++ ssh/terminal/util_windows.go | 4 ++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/ssh/terminal/terminal_test.go b/ssh/terminal/terminal_test.go index a663fe41b..6bdefb4ec 100644 --- a/ssh/terminal/terminal_test.go +++ b/ssh/terminal/terminal_test.go @@ -6,6 +6,7 @@ package terminal import ( "io" + "os" "testing" ) @@ -267,3 +268,24 @@ func TestTerminalSetSize(t *testing.T) { } } } + +func TestMakeRawState(t *testing.T) { + fd := int(os.Stdout.Fd()) + if !IsTerminal(fd) { + t.Skip("stdout is not a terminal; skipping test") + } + + st, err := GetState(fd) + if err != nil { + t.Fatalf("failed to get terminal state from GetState: %s", err) + } + defer Restore(fd, st) + raw, err := MakeRaw(fd) + if err != nil { + t.Fatalf("failed to get terminal state from MakeRaw: %s", err) + } + + if *st != *raw { + t.Errorf("states do not match; was %v, expected %v", raw, st) + } +} diff --git a/ssh/terminal/util_windows.go b/ssh/terminal/util_windows.go index 2dd6c3d97..ae9fa9ec1 100644 --- a/ssh/terminal/util_windows.go +++ b/ssh/terminal/util_windows.go @@ -87,8 +87,8 @@ func MakeRaw(fd int) (*State, error) { if e != 0 { return nil, error(e) } - st &^= (enableEchoInput | enableProcessedInput | enableLineInput | enableProcessedOutput) - _, _, e = syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(st), 0) + raw := st &^ (enableEchoInput | enableProcessedInput | enableLineInput | enableProcessedOutput) + _, _, e = syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(raw), 0) if e != 0 { return nil, error(e) }