Commit b89a9fff authored by Rui Ueyama's avatar Rui Ueyama Committed by Robert Griesemer

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
parent dc008af9
......@@ -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
......
......@@ -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",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment