]> Cypherpunks repositories - gostls13.git/commitdiff
go/printer: avoid stomping on err before checking it
authorTarmigan Casebolt <tarmigan@gmail.com>
Mon, 24 Aug 2015 02:51:26 +0000 (19:51 -0700)
committerRobert Griesemer <gri@golang.org>
Mon, 21 Sep 2015 19:29:26 +0000 (19:29 +0000)
Change-Id: I97ba31e758d3396842ad99a08af696e49a5f1a7d
Reviewed-on: https://go-review.googlesource.com/13954
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/go/printer/printer.go
src/go/printer/printer_test.go

index f9343d3af0d740942e77915ac64228a6b4b243f5..a3eaa6638e30e7e18725a25fe24af1d5b4d0ccc8 100644 (file)
@@ -1178,7 +1178,9 @@ func (p *trimmer) Write(data []byte) (n int, err error) {
                        case '\n', '\f':
                                _, err = p.output.Write(data[m:n])
                                p.resetSpace()
-                               _, err = p.output.Write(aNewline)
+                               if err == nil {
+                                       _, err = p.output.Write(aNewline)
+                               }
                        case tabwriter.Escape:
                                _, err = p.output.Write(data[m:n])
                                p.state = inEscape
index 3b0570e5b502a76f4301bf0985e5a35ae7cb61c3..73f9ead5a3e7beaf454bdd473c2a976b1759e421 100644 (file)
@@ -12,6 +12,7 @@ import (
        "go/ast"
        "go/parser"
        "go/token"
+       "io"
        "io/ioutil"
        "path/filepath"
        "testing"
@@ -548,6 +549,46 @@ func f()
        }
 }
 
+type limitWriter struct {
+       remaining int
+       errCount  int
+}
+
+func (l *limitWriter) Write(buf []byte) (n int, err error) {
+       n = len(buf)
+       if n >= l.remaining {
+               n = l.remaining
+               err = io.EOF
+               l.errCount++
+       }
+       l.remaining -= n
+       return n, err
+}
+
+// Test whether the printer stops writing after the first error
+func TestWriteErrors(t *testing.T) {
+       const filename = "printer.go"
+       src, err := ioutil.ReadFile(filename)
+       if err != nil {
+               panic(err) // error in test
+       }
+       file, err := parser.ParseFile(fset, filename, src, 0)
+       if err != nil {
+               panic(err) // error in test
+       }
+       for i := 0; i < 20; i++ {
+               lw := &limitWriter{remaining: i}
+               err := (&Config{Mode: RawFormat}).Fprint(lw, fset, file)
+               if lw.errCount > 1 {
+                       t.Fatal("Writes continued after first error returned")
+               }
+               // We expect errCount be 1 iff err is set
+               if (lw.errCount != 0) != (err != nil) {
+                       t.Fatal("Expected err when errCount != 0")
+               }
+       }
+}
+
 // TextX is a skeleton test that can be filled in for debugging one-off cases.
 // Do not remove.
 func TestX(t *testing.T) {