From 0519126a3fd0555af996d3e32db04982227ac469 Mon Sep 17 00:00:00 2001 From: Tim Cooper Date: Fri, 26 Jan 2018 16:36:15 -0400 Subject: [PATCH] encoding/hex: fix potential incorrect Dumper output when Close is called multiple times Fixes #23574 Change-Id: I69573de47daa6fd53cc99a78c0c4b867460242e3 Reviewed-on: https://go-review.googlesource.com/90275 Reviewed-by: Brad Fitzpatrick Run-TryBot: Brad Fitzpatrick --- src/encoding/hex/hex.go | 8 +++++++- src/encoding/hex/hex_test.go | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/encoding/hex/hex.go b/src/encoding/hex/hex.go index e4df6cbd4d..edc53954a1 100644 --- a/src/encoding/hex/hex.go +++ b/src/encoding/hex/hex.go @@ -211,6 +211,7 @@ type dumper struct { buf [14]byte used int // number of bytes in the current line n uint // number of bytes, total + closed bool } func toChar(b byte) byte { @@ -221,6 +222,10 @@ func toChar(b byte) byte { } func (h *dumper) Write(data []byte) (n int, err error) { + if h.closed { + return 0, errors.New("encoding/hex: dumper closed") + } + // Output lines look like: // 00000010 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d |./0123456789:;<=| // ^ offset ^ extra space ^ ASCII of line. @@ -277,9 +282,10 @@ func (h *dumper) Write(data []byte) (n int, err error) { func (h *dumper) Close() (err error) { // See the comments in Write() for the details of this format. - if h.used == 0 { + if h.used == 0 || h.closed { return } + h.closed = true h.buf[0] = ' ' h.buf[1] = ' ' h.buf[2] = ' ' diff --git a/src/encoding/hex/hex_test.go b/src/encoding/hex/hex_test.go index b6bab21c48..f222316649 100644 --- a/src/encoding/hex/hex_test.go +++ b/src/encoding/hex/hex_test.go @@ -188,6 +188,22 @@ func TestDumper(t *testing.T) { } } +func TestDumper_doubleclose(t *testing.T) { + var out bytes.Buffer + dumper := Dumper(&out) + + dumper.Write([]byte(`gopher`)) + dumper.Close() + dumper.Close() + dumper.Write([]byte(`gopher`)) + dumper.Close() + + expected := "00000000 67 6f 70 68 65 72 |gopher|\n" + if out.String() != expected { + t.Fatalf("got:\n%#v\nwant:\n%#v", out.String(), expected) + } +} + func TestDump(t *testing.T) { var in [40]byte for i := range in {