]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gofmt: return a proper error for empty Go files
authorDaniel Martí <mvdan@mvdan.cc>
Fri, 18 Mar 2022 10:57:02 +0000 (10:57 +0000)
committerDaniel Martí <mvdan@mvdan.cc>
Thu, 24 Mar 2022 09:17:34 +0000 (09:17 +0000)
I was testing edge cases in gofumpt, a fork of gofmt,
and noticed that gofmt will return a bare io error on empty files,
as demonstrated by the added test case without a fix:

        > ! exec $GOROOT/bin/gofmt empty.go nopackage.go
        [stderr]
        EOF
        nopackage.go:1:1: expected 'package', found not

The problem is the code that detects concurrent modifications.
It relies on ReadFull and correctly deals with io.ErrUnexpectedEOF,
but it did not pay attention to io.EOF, which can happen when size==0.

Change-Id: I6092391721edad4584fb5922d3e3a8fb3da86493
Reviewed-on: https://go-review.googlesource.com/c/go/+/393757
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
Trust: Matt Layher <mdlayher@gmail.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
Trust: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/go/testdata/script/fmt_load_errors.txt
src/cmd/gofmt/gofmt.go

index 559dcc5fe305c466e69b1b65647d8c105b382d3c..e3a9034ede74268463aa8e8cb5c85bf00f64144e 100644 (file)
@@ -16,6 +16,10 @@ stdout 'package x'
 exec $GOROOT/bin/gofmt gofmt-dir
 ! stdout 'package x'
 
+! exec $GOROOT/bin/gofmt empty.go nopackage.go
+stderr -count=1 'empty\.go:1:1: expected .package., found .EOF.'
+stderr -count=1 'nopackage\.go:1:1: expected .package., found not'
+
 -- exclude/empty/x.txt --
 -- exclude/ignore/_x.go --
 package x
@@ -29,3 +33,6 @@ package x
 package x
 -- gofmt-dir/no-extension --
 package x
+-- empty.go --
+-- nopackage.go --
+not the proper start to a Go file
index 8efc88df88707130aafd450cffe060fc90e57eef..5fa883fb56232e65cb3718df0230d3e527b09ed4 100644 (file)
@@ -347,7 +347,12 @@ func readFile(filename string, info fs.FileInfo, in io.Reader) ([]byte, error) {
        // stop to avoid corrupting it.)
        src := make([]byte, size+1)
        n, err := io.ReadFull(in, src)
-       if err != nil && err != io.ErrUnexpectedEOF {
+       switch err {
+       case nil, io.EOF, io.ErrUnexpectedEOF:
+               // io.ReadFull returns io.EOF (for an empty file) or io.ErrUnexpectedEOF
+               // (for a non-empty file) if the file was changed unexpectedly. Continue
+               // with comparing file sizes in those cases.
+       default:
                return nil, err
        }
        if n < size {