]> Cypherpunks repositories - gostls13.git/commitdiff
text/scanner: handle non-io.EOF errors
authorRui Ueyama <ruiu@google.com>
Sat, 22 Mar 2014 00:05:57 +0000 (17:05 -0700)
committerRobert Griesemer <gri@golang.org>
Sat, 22 Mar 2014 00:05:57 +0000 (17:05 -0700)
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
src/pkg/text/scanner/scanner_test.go

index e0d86e343da9f6ac9b593d819a201be007e7408d..db7ca73c68da2459af8f772d16fb6523c177bbba 100644 (file)
@@ -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
index 086ab5660eb935fd0d95eeebda6d4fbe678b34f4..7d3f597eb9ab074168bd2544d17c8f2f4a673869 100644 (file)
@@ -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",