Update deps

This commit is contained in:
Frank Denis 2021-07-03 10:56:53 +02:00
parent f033bb3034
commit 5a091c6da4
1997 changed files with 368830 additions and 2045 deletions

4
vendor/github.com/kyoh86/exportloopref/.golangci.yml generated vendored Normal file
View file

@ -0,0 +1,4 @@
linters:
enable:
- unparam
- exportloopref

43
vendor/github.com/kyoh86/exportloopref/.goreleaser.yml generated vendored Normal file
View file

@ -0,0 +1,43 @@
project_name: exportloopref
release:
github:
owner: kyoh86
name: exportloopref
brews:
- install: |
bin.install "exportloopref"
github:
owner: kyoh86
name: homebrew-tap
folder: Formula
homepage: https://github.com/kyoh86/exportloopref
description: An analyzer that finds exporting pointers for loop variables.
builds:
- goos:
- linux
- darwin
- windows
goarch:
- amd64
- "386"
main: ./cmd/exportloopref
ldflags: -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}
binary: exportloopref
archives:
- id: gzip
format: tar.gz
format_overrides:
- goos: windows
format: zip
name_template: "{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
files:
- licence*
- LICENCE*
- license*
- LICENSE*
- readme*
- README*
- changelog*
- CHANGELOG*
snapshot:
name_template: SNAPSHOT-{{ .Commit }}

21
vendor/github.com/kyoh86/exportloopref/LICENSE generated vendored Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 kyoh86
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
OR OTHER DEALINGS IN THE SOFTWARE.

16
vendor/github.com/kyoh86/exportloopref/Makefile generated vendored Normal file
View file

@ -0,0 +1,16 @@
.PHONY: gen lint test install man
VERSION := `git vertag get`
COMMIT := `git rev-parse HEAD`
gen:
go generate ./...
lint: gen
golangci-lint run
test: lint
go test -v --race ./...
install: test
go install -a -ldflags "-X=main.version=$(VERSION) -X=main.commit=$(COMMIT)" ./...

221
vendor/github.com/kyoh86/exportloopref/README.md generated vendored Normal file
View file

@ -0,0 +1,221 @@
# exportloopref
An analyzer that finds exporting pointers for loop variables.
[![PkgGoDev](https://pkg.go.dev/badge/kyoh86/exportloopref)](https://pkg.go.dev/kyoh86/exportloopref)
[![Go Report Card](https://goreportcard.com/badge/github.com/kyoh86/exportloopref)](https://goreportcard.com/report/github.com/kyoh86/exportloopref)
[![Coverage Status](https://img.shields.io/codecov/c/github/kyoh86/exportloopref.svg)](https://codecov.io/gh/kyoh86/exportloopref)
[![Release](https://github.com/kyoh86/exportloopref/workflows/Release/badge.svg)](https://github.com/kyoh86/exportloopref/releases)
## What's this?
Sample problem code from: https://github.com/kyoh86/exportloopref/blob/master/testdata/src/simple/simple.go
```go
package main
func main() {
var intArray [4]*int
var intSlice []*int
var intRef *int
var intStr struct{ x *int }
println("loop expecting 10, 11, 12, 13")
for i, p := range []int{10, 11, 12, 13} {
printp(&p) // not a diagnostic
intSlice = append(intSlice, &p) // want "exporting a pointer for the loop variable p"
intArray[i] = &p // want "exporting a pointer for the loop variable p"
if i%2 == 0 {
intRef = &p // want "exporting a pointer for the loop variable p"
intStr.x = &p // want "exporting a pointer for the loop variable p"
}
var vStr struct{ x *int }
var vArray [4]*int
var v *int
if i%2 == 0 {
v = &p // not a diagnostic (x is local variable)
vArray[1] = &p // not a diagnostic (x is local variable)
vStr.x = &p
}
_ = v
}
println(`slice expecting "10, 11, 12, 13" but "13, 13, 13, 13"`)
for _, p := range intSlice {
printp(p)
}
println(`array expecting "10, 11, 12, 13" but "13, 13, 13, 13"`)
for _, p := range intArray {
printp(p)
}
println(`captured value expecting "12" but "13"`)
printp(intRef)
}
func printp(p *int) {
println(*p)
}
```
In Go, the `p` variable in the above loops is actually a single variable.
So in many case (like the above), using it makes for us annoying bugs.
You can find them with `exportloopref`, and fix it.
```go
package main
func main() {
var intArray [4]*int
var intSlice []*int
var intRef *int
var intStr struct{ x *int }
println("loop expecting 10, 11, 12, 13")
for i, p := range []int{10, 11, 12, 13} {
p := p // FIX variable into the local variable
printp(&p)
intSlice = append(intSlice, &p)
intArray[i] = &p
if i%2 == 0 {
intRef = &p
intStr.x = &p
}
var vStr struct{ x *int }
var vArray [4]*int
var v *int
if i%2 == 0 {
v = &p
vArray[1] = &p
vStr.x = &p
}
_ = v
}
println(`slice expecting "10, 11, 12, 13"`)
for _, p := range intSlice {
printp(p)
}
println(`array expecting "10, 11, 12, 13"`)
for _, p := range intArray {
printp(p)
}
println(`captured value expecting "12"`)
printp(intRef)
}
func printp(p *int) {
println(*p)
}
```
ref: https://github.com/kyoh86/exportloopref/blob/master/testdata/src/fixed/fixed.go
## Sensing policy
I want to make exportloopref as accurately as possible.
So some cases of lints will be false-negative.
e.g.
```go
var s Foo
for _, p := []int{10, 11, 12, 13} {
s.Bar(&p) // If s stores the pointer, it will be bug.
}
```
If you want to report all of lints (with some false-positives),
you should use [looppointer](https://github.com/kyoh86/looppointer).
### Known false negatives
Case 1: pass the pointer to function to export.
Case 2: pass the pointer to local variable, and export it.
```go
package main
type List []*int
func (l *List) AppendP(p *int) {
*l = append(*l, p)
}
func main() {
var slice []*int
list := List{}
println("loop expect exporting 10, 11, 12, 13")
for _, v := range []int{10, 11, 12, 13} {
list.AppendP(&v) // Case 1: wanted "exporting a pointer for the loop variable v", but cannot be found
p := &v // p is the local variable
slice = append(slice, p) // Case 2: wanted "exporting a pointer for the loop variable v", but cannot be found
}
println(`slice expecting "10, 11, 12, 13" but "13, 13, 13, 13"`)
for _, p := range slice {
printp(p)
}
println(`array expecting "10, 11, 12, 13" but "13, 13, 13, 13"`)
for _, p := range ([]*int)(list) {
printp(p)
}
}
func printp(p *int) {
println(*p)
}
```
## Install
go:
```console
$ go get github.com/kyoh86/exportloopref/cmd/exportloopref
```
[homebrew](https://brew.sh/):
```console
$ brew install kyoh86/tap/exportloopref
```
[gordon](https://github.com/kyoh86/gordon):
```console
$ gordon install kyoh86/exportloopref
```
## Usage
```
exportloopref [-flag] [package]
```
### Flags
| Flag | Description |
| --- | --- |
| -V | print version and exit |
| -all | no effect (deprecated) |
| -c int | display offending line with this many lines of context (default -1) |
| -cpuprofile string | write CPU profile to this file |
| -debug string | debug flags, any subset of "fpstv" |
| -fix | apply all suggested fixes |
| -flags | print analyzer flags in JSON |
| -json | emit JSON output |
| -memprofile string | write memory profile to this file |
| -source | no effect (deprecated) |
| -tags string | no effect (deprecated) |
| -trace string | write trace log to this file |
| -v | no effect (deprecated) |
# LICENSE
[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg)](http://www.opensource.org/licenses/MIT)
This is distributed under the [MIT License](http://www.opensource.org/licenses/MIT).

305
vendor/github.com/kyoh86/exportloopref/exportloopref.go generated vendored Normal file
View file

@ -0,0 +1,305 @@
package exportloopref
import (
"fmt"
"go/ast"
"go/token"
"go/types"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/inspect"
"golang.org/x/tools/go/ast/inspector"
)
var Analyzer = &analysis.Analyzer{
Name: "exportloopref",
Doc: "checks for pointers to enclosing loop variables",
Run: run,
RunDespiteErrors: true,
Requires: []*analysis.Analyzer{inspect.Analyzer},
// ResultType reflect.Type
// FactTypes []Fact
}
func init() {
// Analyzer.Flags.StringVar(&v, "name", "default", "description")
}
func run(pass *analysis.Pass) (interface{}, error) {
inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
search := &Searcher{
Stats: map[token.Pos]struct{}{},
Vars: map[token.Pos]map[token.Pos]struct{}{},
Types: pass.TypesInfo.Types,
}
nodeFilter := []ast.Node{
(*ast.RangeStmt)(nil),
(*ast.ForStmt)(nil),
(*ast.DeclStmt)(nil),
(*ast.AssignStmt)(nil),
(*ast.UnaryExpr)(nil),
}
inspect.WithStack(nodeFilter, func(n ast.Node, push bool, stack []ast.Node) bool {
id, insert, digg := search.Check(n, stack)
if id != nil {
dMsg := fmt.Sprintf("exporting a pointer for the loop variable %s", id.Name)
fMsg := fmt.Sprintf("loop variable %s should be pinned", id.Name)
var suggest []analysis.SuggestedFix
if insert != token.NoPos {
suggest = []analysis.SuggestedFix{{
Message: fMsg,
TextEdits: []analysis.TextEdit{{
Pos: insert,
End: insert,
NewText: []byte(fmt.Sprintf("%[1]s := %[1]s\n", id.Name)),
}},
}}
}
d := analysis.Diagnostic{Pos: id.Pos(),
End: id.End(),
Message: dMsg,
Category: "exportloopref",
SuggestedFixes: suggest,
}
pass.Report(d)
}
return digg
})
return nil, nil
}
type Searcher struct {
// Statement variables : map to collect positions that
// variables are declared like below.
// - for <KEY>, <VALUE> := range ...
// - var <X> int
// - D := ...
Stats map[token.Pos]struct{}
// Local variables maps loop-position, decl-location to ignore
// safe pointers for variable which declared in the loop.
Vars map[token.Pos]map[token.Pos]struct{}
Types map[ast.Expr]types.TypeAndValue
}
func (s *Searcher) Check(n ast.Node, stack []ast.Node) (*ast.Ident, token.Pos, bool) {
switch typed := n.(type) {
case *ast.RangeStmt:
s.parseRangeStmt(typed)
case *ast.ForStmt:
s.parseForStmt(typed)
case *ast.DeclStmt:
s.parseDeclStmt(typed, stack)
case *ast.AssignStmt:
s.parseAssignStmt(typed, stack)
case *ast.UnaryExpr:
return s.checkUnaryExpr(typed, stack)
}
return nil, token.NoPos, true
}
func (s *Searcher) parseRangeStmt(n *ast.RangeStmt) {
s.addStat(n.Key)
s.addStat(n.Value)
}
func (s *Searcher) parseForStmt(n *ast.ForStmt) {
switch post := n.Post.(type) {
case *ast.AssignStmt:
// e.g. for p = head; p != nil; p = p.next
for _, lhs := range post.Lhs {
s.addStat(lhs)
}
case *ast.IncDecStmt:
// e.g. for i := 0; i < n; i++
s.addStat(post.X)
}
}
func (s *Searcher) addStat(expr ast.Expr) {
if id, ok := expr.(*ast.Ident); ok {
s.Stats[id.Pos()] = struct{}{}
}
}
func (s *Searcher) parseDeclStmt(n *ast.DeclStmt, stack []ast.Node) {
loop, _ := s.innermostLoop(stack)
if loop == nil {
return
}
// Register declaring variables
if genDecl, ok := n.Decl.(*ast.GenDecl); ok && genDecl.Tok == token.VAR {
for _, spec := range genDecl.Specs {
for _, name := range spec.(*ast.ValueSpec).Names {
s.addVar(loop, name)
}
}
}
}
func (s *Searcher) parseAssignStmt(n *ast.AssignStmt, stack []ast.Node) {
loop, _ := s.innermostLoop(stack)
if loop == nil {
return
}
// Find statements declaring local variable
if n.Tok == token.DEFINE {
for _, h := range n.Lhs {
s.addVar(loop, h)
}
}
}
func (s *Searcher) addVar(loop ast.Node, expr ast.Expr) {
loopPos := loop.Pos()
id, ok := expr.(*ast.Ident)
if !ok {
return
}
vars, ok := s.Vars[loopPos]
if !ok {
vars = map[token.Pos]struct{}{}
}
vars[id.Obj.Pos()] = struct{}{}
s.Vars[loopPos] = vars
}
func insertionPosition(block *ast.BlockStmt) token.Pos {
if len(block.List) > 0 {
return block.List[0].Pos()
}
return token.NoPos
}
func (s *Searcher) innermostLoop(stack []ast.Node) (ast.Node, token.Pos) {
for i := len(stack) - 1; i >= 0; i-- {
switch typed := stack[i].(type) {
case *ast.RangeStmt:
return typed, insertionPosition(typed.Body)
case *ast.ForStmt:
return typed, insertionPosition(typed.Body)
}
}
return nil, token.NoPos
}
func (s *Searcher) checkUnaryExpr(n *ast.UnaryExpr, stack []ast.Node) (*ast.Ident, token.Pos, bool) {
loop, insert := s.innermostLoop(stack)
if loop == nil {
return nil, token.NoPos, true
}
if n.Op != token.AND {
return nil, token.NoPos, true
}
// Get identity of the referred item
id := s.getIdentity(n.X)
if id == nil {
return nil, token.NoPos, true
}
// If the identity is not the loop statement variable,
// it will not be reported.
if _, isStat := s.Stats[id.Obj.Pos()]; !isStat {
return nil, token.NoPos, true
}
// check stack append(), []X{}, map[Type]X{}, Struct{}, &Struct{}, X.(Type), (X)
// in the <outer> =
var mayRHPos token.Pos
for i := len(stack) - 2; i >= 0; i-- {
switch typed := stack[i].(type) {
case (*ast.UnaryExpr):
// noop
case (*ast.CompositeLit):
// noop
case (*ast.KeyValueExpr):
// noop
case (*ast.CallExpr):
fun, ok := typed.Fun.(*ast.Ident)
if !ok {
return nil, token.NoPos, false // it's calling a function other of `append`. It cannot be checked
}
if fun.Name != "append" {
return nil, token.NoPos, false // it's calling a function other of `append`. It cannot be checked
}
case (*ast.AssignStmt):
if len(typed.Rhs) != len(typed.Lhs) {
return nil, token.NoPos, false // dead logic
}
// search x where Rhs[x].Pos() == mayRHPos
var index int
for ri, rh := range typed.Rhs {
if rh.Pos() == mayRHPos {
index = ri
break
}
}
// check Lhs[x] is not local variable
lh := typed.Lhs[index]
isVar := s.isVar(loop, lh)
if !isVar {
return id, insert, false
}
return nil, token.NoPos, true
default:
// Other statement is not able to be checked.
return nil, token.NoPos, false
}
// memory an expr that may be right-hand in the AssignStmt
mayRHPos = stack[i].Pos()
}
return nil, token.NoPos, true
}
func (s *Searcher) isVar(loop ast.Node, expr ast.Expr) bool {
vars := s.Vars[loop.Pos()] // map[token.Pos]struct{}
if vars == nil {
return false
}
switch typed := expr.(type) {
case (*ast.Ident):
_, isVar := vars[typed.Obj.Pos()]
return isVar
case (*ast.IndexExpr): // like X[Y], check X
return s.isVar(loop, typed.X)
case (*ast.SelectorExpr): // like X.Y, check X
return s.isVar(loop, typed.X)
}
return false
}
// Get variable identity
func (s *Searcher) getIdentity(expr ast.Expr) *ast.Ident {
switch typed := expr.(type) {
case *ast.SelectorExpr:
// Ignore if the parent is pointer ref (fix for #2)
if _, ok := s.Types[typed.X].Type.(*types.Pointer); ok {
return nil
}
// Get parent identity; i.e. `a.b` of the `a.b.c`.
return s.getIdentity(typed.X)
case *ast.Ident:
// Get simple identity; i.e. `a` of the `a`.
if typed.Obj == nil {
return nil
}
return typed
}
return nil
}

5
vendor/github.com/kyoh86/exportloopref/go.mod generated vendored Normal file
View file

@ -0,0 +1,5 @@
module github.com/kyoh86/exportloopref
go 1.14
require golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa

20
vendor/github.com/kyoh86/exportloopref/go.sum generated vendored Normal file
View file

@ -0,0 +1,20 @@
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa h1:mMXQKlWCw9mIWgVLLfiycDZjMHMMYqiuakI4E/l2xcA=
golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=