From b89a9fff5eee0eab8cb98d3c6532a8613dfdf580 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Fri, 21 Mar 2014 17:05:57 -0700 Subject: [PATCH] text/scanner: handle non-io.EOF errors Currently Scan ignores an error returned from source if the number of bytes source has read is 0. Fixes #7594. LGTM=gri R=golang-codereviews, bradfitz, gri CC=golang-codereviews https://golang.org/cl/78120043 --- src/pkg/text/scanner/scanner.go | 6 +++--- src/pkg/text/scanner/scanner_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/pkg/text/scanner/scanner.go b/src/pkg/text/scanner/scanner.go index e0d86e343d..db7ca73c68 100644 --- a/src/pkg/text/scanner/scanner.go +++ b/src/pkg/text/scanner/scanner.go @@ -240,6 +240,9 @@ func (s *Scanner) next() rune { s.srcEnd = i + n s.srcBuf[s.srcEnd] = utf8.RuneSelf // sentinel if err != nil { + if err != io.EOF { + s.error(err.Error()) + } if s.srcEnd == 0 { if s.lastCharLen > 0 { // previous character was not EOF @@ -248,9 +251,6 @@ func (s *Scanner) next() rune { s.lastCharLen = 0 return EOF } - if err != io.EOF { - s.error(err.Error()) - } // If err == EOF, we won't be getting more // bytes; break to avoid infinite loop. If // err is something else, we don't know if diff --git a/src/pkg/text/scanner/scanner_test.go b/src/pkg/text/scanner/scanner_test.go index 086ab5660e..7d3f597eb9 100644 --- a/src/pkg/text/scanner/scanner_test.go +++ b/src/pkg/text/scanner/scanner_test.go @@ -462,6 +462,33 @@ func TestError(t *testing.T) { testError(t, `/*/`, "1:4", "comment not terminated", EOF) } +// An errReader returns (0, err) where err is not io.EOF. +type errReader struct{} + +func (errReader) Read(b []byte) (int, error) { + return 0, io.ErrNoProgress // some error that is not io.EOF +} + +func TestIOError(t *testing.T) { + s := new(Scanner).Init(errReader{}) + errorCalled := false + s.Error = func(s *Scanner, msg string) { + if !errorCalled { + if want := io.ErrNoProgress.Error(); msg != want { + t.Errorf("msg = %q, want %q", msg, want) + } + errorCalled = true + } + } + tok := s.Scan() + if tok != EOF { + t.Errorf("tok = %s, want EOF", TokenString(tok)) + } + if !errorCalled { + t.Errorf("error handler not called") + } +} + func checkPos(t *testing.T, got, want Position) { if got.Offset != want.Offset || got.Line != want.Line || got.Column != want.Column { t.Errorf("got offset, line, column = %d, %d, %d; want %d, %d, %d", -- 2.48.1