go: cmd/vet: detect "defer resp.Body.Close()"s that will panic
This is a simple newbie mistake I saw in the Go code I wrote many years ago:
resp, err := http.Get(...)
defer resp.Body.Close()
if err != nil {
return err
}
// read resp.Body or something
This will panic when resp == nil
which is iff err != nil
. Can go vet
have a heuristic for when resp.Body.Close()
is invoked in a path where neither of the following are checked:
resp != nil
err != nil
I don’t know the specifics of how cmd/vet works but I was a little surprised when no static analysis tools caught this one so far (obviously points to lack of testing on my end as well, however I feel like static analysis could’ve found it earlier).
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Comments: 17 (16 by maintainers)
@ahmetalpbalkan, FYI, I know that
staticcheck
does catch this issue (and similar ones, like withos.Open
, etc.):For example, if I run it on the following program:
The output is:
Frequency could be covered by generalizing the check: instead of looking for
resp.Body
specifically, report all guaranteed nil dereferences, and all dead code caused byif x == nil
conditions in which x is known to be always nil (or always non-nil). You’d also need to tell it that some functions like http.Get return zero when err != nil, thought it could figure this out for most functions in the same package.I ran this check across Google’s Go code and it found a lot of errors, some quite hard to spot. That implementation used golang.org/x/tools/go/ssa, which needs well-typed input, but it would not be hard to make it build sound SSA output from unsound source input, inserting special “fatal” operators as needed to smooth over the gaps. I’m not sure cmd/vet wants to bundle a copy of x/tools/go/ssa, though.
On 13 November 2016 at 18:43, Dmitri Shuralyov notifications@github.com wrote:
@robpike is the decider.
Seems like a reasonable rule, at least when limited specifically to net/http: No false positives, easy to get wrong, might not be caught during testing because most http requests don’t fail, blows up in a bad way when something does go wrong.