diff options
| author | dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> | 2023-08-22 02:02:22 +0000 |
|---|---|---|
| committer | Taras Madan <tarasmadan@google.com> | 2023-08-22 12:20:16 +0000 |
| commit | 91132985a7ff76db390949ac765113cfd3178fa7 (patch) | |
| tree | 9dcdece9df519c487f06e1b7a824c7ddd571ce53 /vendor/github.com | |
| parent | 81191e0ae93e179f148ee4f89deedfe444d7baaa (diff) | |
mod: do: bump github.com/golangci/golangci-lint from 1.54.1 to 1.54.2
Bumps [github.com/golangci/golangci-lint](https://github.com/golangci/golangci-lint) from 1.54.1 to 1.54.2.
- [Release notes](https://github.com/golangci/golangci-lint/releases)
- [Changelog](https://github.com/golangci/golangci-lint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/golangci/golangci-lint/compare/v1.54.1...v1.54.2)
---
updated-dependencies:
- dependency-name: github.com/golangci/golangci-lint
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
Diffstat (limited to 'vendor/github.com')
54 files changed, 1035 insertions, 246 deletions
diff --git a/vendor/github.com/Antonboom/errname/pkg/analyzer/analyzer.go b/vendor/github.com/Antonboom/errname/pkg/analyzer/analyzer.go index 6425db137..aa8522510 100644 --- a/vendor/github.com/Antonboom/errname/pkg/analyzer/analyzer.go +++ b/vendor/github.com/Antonboom/errname/pkg/analyzer/analyzer.go @@ -1,6 +1,7 @@ package analyzer import ( + "fmt" "go/ast" "go/token" "strconv" @@ -25,16 +26,16 @@ func New() *analysis.Analyzer { type stringSet = map[string]struct{} var ( - imports = []ast.Node{(*ast.ImportSpec)(nil)} - types = []ast.Node{(*ast.TypeSpec)(nil)} - funcs = []ast.Node{(*ast.FuncDecl)(nil)} + importNodes = []ast.Node{(*ast.ImportSpec)(nil)} + typeNodes = []ast.Node{(*ast.TypeSpec)(nil)} + funcNodes = []ast.Node{(*ast.FuncDecl)(nil)} ) func run(pass *analysis.Pass) (interface{}, error) { insp := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) pkgAliases := map[string]string{} - insp.Preorder(imports, func(node ast.Node) { + insp.Preorder(importNodes, func(node ast.Node) { i := node.(*ast.ImportSpec) if n := i.Name; n != nil && i.Path != nil { if path, err := strconv.Unquote(i.Path.Value); err == nil { @@ -45,14 +46,14 @@ func run(pass *analysis.Pass) (interface{}, error) { allTypes := stringSet{} typesSpecs := map[string]*ast.TypeSpec{} - insp.Preorder(types, func(node ast.Node) { + insp.Preorder(typeNodes, func(node ast.Node) { t := node.(*ast.TypeSpec) allTypes[t.Name.Name] = struct{}{} typesSpecs[t.Name.Name] = t }) errorTypes := stringSet{} - insp.Preorder(funcs, func(node ast.Node) { + insp.Preorder(funcNodes, func(node ast.Node) { f := node.(*ast.FuncDecl) t, ok := isMethodError(f) if !ok { @@ -62,7 +63,7 @@ func run(pass *analysis.Pass) (interface{}, error) { tSpec, ok := typesSpecs[t] if !ok { - panic("no specification for type " + t) + panic(fmt.Sprintf("no specification for type %q", t)) } if _, ok := tSpec.Type.(*ast.ArrayType); ok { @@ -75,7 +76,7 @@ func run(pass *analysis.Pass) (interface{}, error) { }) errorFuncs := stringSet{} - insp.Preorder(funcs, func(node ast.Node) { + insp.Preorder(funcNodes, func(node ast.Node) { f := node.(*ast.FuncDecl) if isFuncReturningErr(f.Type, allTypes, errorTypes) { errorFuncs[f.Name.Name] = struct{}{} diff --git a/vendor/github.com/Antonboom/errname/pkg/analyzer/facts.go b/vendor/github.com/Antonboom/errname/pkg/analyzer/facts.go index 8711f9cf5..06f8d61d8 100644 --- a/vendor/github.com/Antonboom/errname/pkg/analyzer/facts.go +++ b/vendor/github.com/Antonboom/errname/pkg/analyzer/facts.go @@ -1,8 +1,10 @@ package analyzer import ( + "fmt" "go/ast" "go/token" + "go/types" "strings" "unicode" ) @@ -34,15 +36,19 @@ func isMethodError(f *ast.FuncDecl) (typeName string, ok bool) { if i, ok := v.X.(*ast.Ident); ok { return i.Name } + case *ast.IndexListExpr: + if i, ok := v.X.(*ast.Ident); ok { + return i.Name + } } - return "" + panic(fmt.Errorf("unsupported Error() receiver type %q", types.ExprString(e))) } switch rt := f.Recv.List[0].Type; v := rt.(type) { - case *ast.Ident, *ast.IndexExpr: // SomeError, SomeError[T] + case *ast.Ident, *ast.IndexExpr, *ast.IndexListExpr: // SomeError, SomeError[T], SomeError[T1, T2, ...] receiverType = unwrapIdentName(rt) - case *ast.StarExpr: // *SomeError, *SomeError[T] + case *ast.StarExpr: // *SomeError, *SomeError[T], *SomeError[T1, T2, ...] receiverType = unwrapIdentName(v.X) } diff --git a/vendor/github.com/Antonboom/nilnil/pkg/analyzer/analyzer.go b/vendor/github.com/Antonboom/nilnil/pkg/analyzer/analyzer.go index 6bed7696a..e980db546 100644 --- a/vendor/github.com/Antonboom/nilnil/pkg/analyzer/analyzer.go +++ b/vendor/github.com/Antonboom/nilnil/pkg/analyzer/analyzer.go @@ -89,7 +89,7 @@ func (n *nilNil) run(pass *analysis.Pass) (interface{}, error) { fRes1, fRes2 := ft.Results.List[0], ft.Results.List[1] if !(n.isDangerNilField(fRes1, typeSpecs) && n.isErrorField(fRes2)) { - return + return false } rRes1, rRes2 := v.Results[0], v.Results[1] diff --git a/vendor/github.com/ccojocar/zxcvbn-go/.gitignore b/vendor/github.com/ccojocar/zxcvbn-go/.gitignore new file mode 100644 index 000000000..e032cc2fc --- /dev/null +++ b/vendor/github.com/ccojocar/zxcvbn-go/.gitignore @@ -0,0 +1,5 @@ +zxcvbn +debug.test + +# SBOMs generated during CI +/bom.json diff --git a/vendor/github.com/ccojocar/zxcvbn-go/.golangci.yml b/vendor/github.com/ccojocar/zxcvbn-go/.golangci.yml new file mode 100644 index 000000000..b54f70092 --- /dev/null +++ b/vendor/github.com/ccojocar/zxcvbn-go/.golangci.yml @@ -0,0 +1,39 @@ +linters: + enable: + - asciicheck + - bodyclose + - dogsled + - durationcheck + - errcheck + - errorlint + - exportloopref + - gci + - ginkgolinter + - gofmt + - gofumpt + - goimports + - gosimple + - govet + - importas + - ineffassign + - megacheck + - misspell + - nakedret + - nolintlint + - revive + - staticcheck + - typecheck + - unconvert + - unparam + - unused + - wastedassign + +linters-settings: + gci: + sections: + - standard + - default + - prefix(github.com/ccojocar) + +run: + timeout: 5m diff --git a/vendor/github.com/ccojocar/zxcvbn-go/.goreleaser.yml b/vendor/github.com/ccojocar/zxcvbn-go/.goreleaser.yml new file mode 100644 index 000000000..2386aeee5 --- /dev/null +++ b/vendor/github.com/ccojocar/zxcvbn-go/.goreleaser.yml @@ -0,0 +1,27 @@ +--- +project_name: zxcvbn-go + +release: + extra_files: + - glob: ./bom.json + github: + owner: ccojocar + name: zxcvbn-go + +builds: + - main: ./testapp/ + binary: zxcvbn-go + goos: + - darwin + - linux + - windows + goarch: + - amd64 + - arm64 + - s390x + ldflags: -X main.Version={{.Version}} -X main.GitTag={{.Tag}} -X main.BuildDate={{.Date}} + env: + - CGO_ENABLED=0 + +gomod: + proxy: true diff --git a/vendor/github.com/nbutton23/zxcvbn-go/LICENSE.txt b/vendor/github.com/ccojocar/zxcvbn-go/LICENSE.txt index e8f59e06d..e8f59e06d 100644 --- a/vendor/github.com/nbutton23/zxcvbn-go/LICENSE.txt +++ b/vendor/github.com/ccojocar/zxcvbn-go/LICENSE.txt diff --git a/vendor/github.com/ccojocar/zxcvbn-go/Makefile b/vendor/github.com/ccojocar/zxcvbn-go/Makefile new file mode 100644 index 000000000..0690f3753 --- /dev/null +++ b/vendor/github.com/ccojocar/zxcvbn-go/Makefile @@ -0,0 +1,61 @@ +GIT_TAG?= $(shell git describe --always --tags) +BIN = zxcvbn-go +FMT_CMD = $(gofmt -s -l -w $(find . -type f -name '*.go' -not -path './vendor/*') | tee /dev/stderr) +IMAGE_REPO = ccojocar +DATE_FMT=+%Y-%m-%d +ifdef SOURCE_DATE_EPOCH + BUILD_DATE ?= $(shell date -u -d "@$(SOURCE_DATE_EPOCH)" "$(DATE_FMT)" 2>/dev/null || date -u -r "$(SOURCE_DATE_EPOCH)" "$(DATE_FMT)" 2>/dev/null || date -u "$(DATE_FMT)") +else + BUILD_DATE ?= $(shell date "$(DATE_FMT)") +endif +BUILDFLAGS := "-w -s -X 'main.Version=$(GIT_TAG)' -X 'main.GitTag=$(GIT_TAG)' -X 'main.BuildDate=$(BUILD_DATE)'" +CGO_ENABLED = 0 +GO := GO111MODULE=on go +GO_NOMOD :=GO111MODULE=off go +GOPATH ?= $(shell $(GO) env GOPATH) +GOBIN ?= $(GOPATH)/bin +GO_MINOR_VERSION = $(shell $(GO) version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f2) +GOVULN_MIN_VERSION = 17 +GO_VERSION = 1.20 + +default: + $(MAKE) test + +install-govulncheck: + @if [ $(GO_MINOR_VERSION) -gt $(GOVULN_MIN_VERSION) ]; then \ + go install golang.org/x/vuln/cmd/govulncheck@latest; \ + fi + +test-all: fmt vet lint sec govulncheck test + +test: + go test -v ./... + +fmt: + @echo "FORMATTING" + @FORMATTED=`$(GO) fmt ./...` + @([ ! -z "$(FORMATTED)" ] && printf "Fixed unformatted files:\n$(FORMATTED)") || true + +vet: + @echo "VETTING" + $(GO) vet ./... + +lint: + @echo "LINTING: golangci-lint" + golangci-lint run + +sec: + @echo "SECURITY SCANNING" + gosec ./... + +govulncheck: install-govulncheck + @echo "CHECKING VULNERABILITIES" + @if [ $(GO_MINOR_VERSION) -gt $(GOVULN_MIN_VERSION) ]; then \ + govulncheck ./...; \ + fi + +clean: + rm -rf build vendor dist coverage.txt + rm -f release image $(BIN) + +.PHONY: test test-all fmt vet govulncheck clean diff --git a/vendor/github.com/nbutton23/zxcvbn-go/README.md b/vendor/github.com/ccojocar/zxcvbn-go/README.md index 3f742a9da..3f742a9da 100644 --- a/vendor/github.com/nbutton23/zxcvbn-go/README.md +++ b/vendor/github.com/ccojocar/zxcvbn-go/README.md diff --git a/vendor/github.com/nbutton23/zxcvbn-go/adjacency/adjcmartix.go b/vendor/github.com/ccojocar/zxcvbn-go/adjacency/adjcmartix.go index 66ad30b82..34526685c 100644 --- a/vendor/github.com/nbutton23/zxcvbn-go/adjacency/adjcmartix.go +++ b/vendor/github.com/ccojocar/zxcvbn-go/adjacency/adjcmartix.go @@ -4,7 +4,7 @@ import ( "encoding/json" "log" - "github.com/nbutton23/zxcvbn-go/data" + "github.com/ccojocar/zxcvbn-go/data" ) // Graph holds information about different graphs @@ -25,7 +25,7 @@ func init() { GraphMap["l33t"] = BuildLeet() } -//BuildQwerty builds the Qwerty Graph +// BuildQwerty builds the Qwerty Graph func BuildQwerty() Graph { data, err := data.Asset("data/Qwerty.json") if err != nil { @@ -34,7 +34,7 @@ func BuildQwerty() Graph { return getAdjancencyGraphFromFile(data, "qwerty") } -//BuildDvorak builds the Dvorak Graph +// BuildDvorak builds the Dvorak Graph func BuildDvorak() Graph { data, err := data.Asset("data/Dvorak.json") if err != nil { @@ -43,7 +43,7 @@ func BuildDvorak() Graph { return getAdjancencyGraphFromFile(data, "dvorak") } -//BuildKeypad builds the Keypad Graph +// BuildKeypad builds the Keypad Graph func BuildKeypad() Graph { data, err := data.Asset("data/Keypad.json") if err != nil { @@ -52,7 +52,7 @@ func BuildKeypad() Graph { return getAdjancencyGraphFromFile(data, "keypad") } -//BuildMacKeypad builds the Mac Keypad Graph +// BuildMacKeypad builds the Mac Keypad Graph func BuildMacKeypad() Graph { data, err := data.Asset("data/MacKeypad.json") if err != nil { @@ -61,7 +61,7 @@ func BuildMacKeypad() Graph { return getAdjancencyGraphFromFile(data, "mac_keypad") } -//BuildLeet builds the L33T Graph +// BuildLeet builds the L33T Graph func BuildLeet() Graph { data, err := data.Asset("data/L33t.json") if err != nil { @@ -71,7 +71,6 @@ func BuildLeet() Graph { } func getAdjancencyGraphFromFile(data []byte, name string) Graph { - var graph Graph err := json.Unmarshal(data, &graph) if err != nil { @@ -82,9 +81,9 @@ func getAdjancencyGraphFromFile(data []byte, name string) Graph { } // CalculateAvgDegree calclates the average degree between nodes in the graph -//on qwerty, 'g' has degree 6, being adjacent to 'ftyhbv'. '\' has degree 1. -//this calculates the average over all keys. -//TODO double check that i ported this correctly scoring.coffee ln 5 +// on qwerty, 'g' has degree 6, being adjacent to 'ftyhbv'. '\' has degree 1. +// this calculates the average over all keys. +// TODO double check that i ported this correctly scoring.coffee ln 5 func (adjGrp Graph) CalculateAvgDegree() float64 { if adjGrp.averageDegree != float64(0) { return adjGrp.averageDegree @@ -92,14 +91,12 @@ func (adjGrp Graph) CalculateAvgDegree() float64 { var avg float64 var count float64 for _, value := range adjGrp.Graph { - for _, char := range value { if len(char) != 0 || char != " " { avg += float64(len(char)) count++ } } - } adjGrp.averageDegree = avg / count diff --git a/vendor/github.com/nbutton23/zxcvbn-go/data/bindata.go b/vendor/github.com/ccojocar/zxcvbn-go/data/bindata.go index f3a0c010c..3db0f1b10 100644 --- a/vendor/github.com/nbutton23/zxcvbn-go/data/bindata.go +++ b/vendor/github.com/ccojocar/zxcvbn-go/data/bindata.go @@ -33,7 +33,7 @@ func bindataRead(data []byte, name string) ([]byte, error) { } var buf bytes.Buffer - _, err = io.Copy(&buf, gz) + _, err = io.Copy(&buf, gz) // #nosec clErr := gz.Close() if err != nil { @@ -345,11 +345,13 @@ var _bindata = map[string]func() (*asset, error){ // directory embedded in the file by go-bindata. // For example if you run go-bindata on data/... and data contains the // following hierarchy: -// data/ -// foo.txt -// img/ -// a.png -// b.png +// +// data/ +// foo.txt +// img/ +// a.png +// b.png +// // then AssetDir("data") would return []string{"foo.txt", "img"} // AssetDir("data/img") would return []string{"a.png", "b.png"} // AssetDir("foo.txt") and AssetDir("notexist") would return an error diff --git a/vendor/github.com/nbutton23/zxcvbn-go/entropy/entropyCalculator.go b/vendor/github.com/ccojocar/zxcvbn-go/entropy/entropyCalculator.go index 8f57ea0a4..80432572b 100644 --- a/vendor/github.com/nbutton23/zxcvbn-go/entropy/entropyCalculator.go +++ b/vendor/github.com/ccojocar/zxcvbn-go/entropy/entropyCalculator.go @@ -1,12 +1,13 @@ package entropy import ( - "github.com/nbutton23/zxcvbn-go/adjacency" - "github.com/nbutton23/zxcvbn-go/match" - "github.com/nbutton23/zxcvbn-go/utils/math" "math" "regexp" "unicode" + + "github.com/ccojocar/zxcvbn-go/adjacency" + "github.com/ccojocar/zxcvbn-go/match" + zxcvbnmath "github.com/ccojocar/zxcvbn-go/utils/math" ) const ( @@ -27,7 +28,7 @@ var ( func DictionaryEntropy(match match.Match, rank float64) float64 { baseEntropy := math.Log2(rank) upperCaseEntropy := extraUpperCaseEntropy(match) - //TODO: L33t + // TODO: L33t return baseEntropy + upperCaseEntropy } @@ -46,18 +47,18 @@ func extraUpperCaseEntropy(match match.Match) float64 { return float64(0) } - //a capitalized word is the most common capitalization scheme, - //so it only doubles the search space (uncapitalized + capitalized): 1 extra bit of entropy. - //allcaps and end-capitalized are common enough too, underestimate as 1 extra bit to be safe. + // a capitalized word is the most common capitalization scheme, + // so it only doubles the search space (uncapitalized + capitalized): 1 extra bit of entropy. + // allcaps and end-capitalized are common enough too, underestimate as 1 extra bit to be safe. for _, matcher := range []*regexp.Regexp{startUpperRx, endUpperRx, allUpperRx} { if matcher.MatchString(word) { return float64(1) } } - //Otherwise calculate the number of ways to capitalize U+L uppercase+lowercase letters with U uppercase letters or - //less. Or, if there's more uppercase than lower (for e.g. PASSwORD), the number of ways to lowercase U+L letters - //with L lowercase letters or less. + // Otherwise calculate the number of ways to capitalize U+L uppercase+lowercase letters with U uppercase letters or + // less. Or, if there's more uppercase than lower (for e.g. PASSwORD), the number of ways to lowercase U+L letters + // with L lowercase letters or less. countUpper, countLower := float64(0), float64(0) for _, char := range word { @@ -71,21 +72,21 @@ func extraUpperCaseEntropy(match match.Match) float64 { var possibililities float64 for i := float64(0); i <= math.Min(countUpper, countLower); i++ { - possibililities += float64(zxcvbnmath.NChoseK(totalLenght, i)) + possibililities += zxcvbnmath.NChoseK(totalLenght, i) } if possibililities < 1 { return float64(1) } - return float64(math.Log2(possibililities)) + return (math.Log2(possibililities)) } // SpatialEntropy calculates the entropy for spatial matches func SpatialEntropy(match match.Match, turns int, shiftCount int) float64 { var s, d float64 if match.DictionaryName == "qwerty" || match.DictionaryName == "dvorak" { - //todo: verify qwerty and dvorak have the same length and degree + // todo: verify qwerty and dvorak have the same length and degree s = float64(len(adjacency.BuildQwerty().Graph)) d = adjacency.BuildQwerty().CalculateAvgDegree() } else { @@ -97,8 +98,8 @@ func SpatialEntropy(match match.Match, turns int, shiftCount int) float64 { length := float64(len(match.Token)) - //TODO: Should this be <= or just < ? - //Estimate the number of possible patterns w/ length L or less with t turns or less + // TODO: Should this be <= or just < ? + // Estimate the number of possible patterns w/ length L or less with t turns or less for i := float64(2); i <= length+1; i++ { possibleTurns := math.Min(float64(turns), i-1) for j := float64(1); j <= possibleTurns+1; j++ { @@ -108,8 +109,8 @@ func SpatialEntropy(match match.Match, turns int, shiftCount int) float64 { } entropy := math.Log2(possibilities) - //add extra entropu for shifted keys. ( % instead of 5 A instead of a) - //Math is similar to extra entropy for uppercase letters in dictionary matches. + // add extra entropu for shifted keys. ( % instead of 5 A instead of a) + // Math is similar to extra entropy for uppercase letters in dictionary matches. if S := float64(shiftCount); S > float64(0) { possibilities = float64(0) @@ -134,7 +135,7 @@ func RepeatEntropy(match match.Match) float64 { } // CalcBruteForceCardinality calculates the brute force cardinality -//TODO: Validate against python +// TODO: Validate against python func CalcBruteForceCardinality(password string) float64 { lower, upper, digits, symbols := float64(0), float64(0), float64(0), float64(0) @@ -157,12 +158,12 @@ func CalcBruteForceCardinality(password string) float64 { // SequenceEntropy calculates the entropy for sequences such as 4567 or cdef func SequenceEntropy(match match.Match, dictionaryLength int, ascending bool) float64 { firstChar := match.Token[0] - baseEntropy := float64(0) + var baseEntropy float64 if string(firstChar) == "a" || string(firstChar) == "1" { baseEntropy = float64(0) } else { baseEntropy = math.Log2(float64(dictionaryLength)) - //TODO: should this be just the first or any char? + // TODO: should this be just the first or any char? if unicode.IsUpper(rune(firstChar)) { baseEntropy++ } @@ -183,7 +184,7 @@ func ExtraLeetEntropy(match match.Match, password string) float64 { if string(char) != string(match.Token[index]) { subsitutions++ } else { - //TODO: Make this only true for 1337 chars that are not subs? + // TODO: Make this only true for 1337 chars that are not subs? unsub++ } } @@ -210,7 +211,7 @@ func DateEntropy(dateMatch match.DateMatch) float64 { } if dateMatch.Separator != "" { - entropy += 2 //add two bits for separator selection [/,-,.,etc] + entropy += 2 // add two bits for separator selection [/,-,.,etc] } return entropy } diff --git a/vendor/github.com/nbutton23/zxcvbn-go/frequency/frequency.go b/vendor/github.com/ccojocar/zxcvbn-go/frequency/frequency.go index d056e4d4e..4f51369e1 100644 --- a/vendor/github.com/nbutton23/zxcvbn-go/frequency/frequency.go +++ b/vendor/github.com/ccojocar/zxcvbn-go/frequency/frequency.go @@ -4,7 +4,7 @@ import ( "encoding/json" "log" - "github.com/nbutton23/zxcvbn-go/data" + "github.com/ccojocar/zxcvbn-go/data" ) // List holds a frequency list @@ -28,8 +28,8 @@ func init() { Lists["Surname"] = getStringListFromAsset(surnameFilePath, "Surname") Lists["English"] = getStringListFromAsset(englishFilePath, "English") Lists["Passwords"] = getStringListFromAsset(passwordsFilePath, "Passwords") - } + func getAsset(name string) []byte { data, err := data.Asset(name) if err != nil { @@ -38,8 +38,8 @@ func getAsset(name string) []byte { return data } -func getStringListFromAsset(data []byte, name string) List { +func getStringListFromAsset(data []byte, name string) List { var tempList List err := json.Unmarshal(data, &tempList) if err != nil { diff --git a/vendor/github.com/nbutton23/zxcvbn-go/match/match.go b/vendor/github.com/ccojocar/zxcvbn-go/match/match.go index dd30bea04..998dde111 100644 --- a/vendor/github.com/nbutton23/zxcvbn-go/match/match.go +++ b/vendor/github.com/ccojocar/zxcvbn-go/match/match.go @@ -1,14 +1,16 @@ package match -//Matches is an alies for []Match used for sorting +// Matches is an alies for []Match used for sorting type Matches []Match func (s Matches) Len() int { return len(s) } + func (s Matches) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + func (s Matches) Less(i, j int) bool { if s[i].I < s[j].I { return true @@ -28,7 +30,7 @@ type Match struct { Entropy float64 } -//DateMatch is specifilly a match for type date +// DateMatch is specifilly a match for type date type DateMatch struct { Pattern string I, J int @@ -37,7 +39,7 @@ type DateMatch struct { Day, Month, Year int64 } -//Matcher are a func and ID that can be used to match different passwords +// Matcher are a func and ID that can be used to match different passwords type Matcher struct { MatchingFunc func(password string) []Match ID string diff --git a/vendor/github.com/nbutton23/zxcvbn-go/matching/dateMatchers.go b/vendor/github.com/ccojocar/zxcvbn-go/matching/dateMatchers.go index 8dfdf2410..fd7f38332 100644 --- a/vendor/github.com/nbutton23/zxcvbn-go/matching/dateMatchers.go +++ b/vendor/github.com/ccojocar/zxcvbn-go/matching/dateMatchers.go @@ -5,8 +5,8 @@ import ( "strconv" "strings" - "github.com/nbutton23/zxcvbn-go/entropy" - "github.com/nbutton23/zxcvbn-go/match" + "github.com/ccojocar/zxcvbn-go/entropy" + "github.com/ccojocar/zxcvbn-go/match" ) const ( @@ -20,12 +20,12 @@ var ( dateWithOutSepMatch = regexp.MustCompile(`\d{4,8}`) ) -//FilterDateSepMatcher can be pass to zxcvbn-go.PasswordStrength to skip that matcher +// FilterDateSepMatcher can be pass to zxcvbn-go.PasswordStrength to skip that matcher func FilterDateSepMatcher(m match.Matcher) bool { return m.ID == dateSepMatcherName } -//FilterDateWithoutSepMatcher can be pass to zxcvbn-go.PasswordStrength to skip that matcher +// FilterDateWithoutSepMatcher can be pass to zxcvbn-go.PasswordStrength to skip that matcher func FilterDateWithoutSepMatcher(m match.Matcher) bool { return m.ID == dateWithOutSepMatcherName } @@ -64,8 +64,8 @@ func dateSepMatcher(password string) []match.Match { return matches } -func dateSepMatchHelper(password string) []match.DateMatch { +func dateSepMatchHelper(password string) []match.DateMatch { var matches []match.DateMatch for _, v := range dateRxYearSuffix.FindAllString(password, len(password)) { @@ -101,7 +101,6 @@ func dateSepMatchHelper(password string) []match.DateMatch { } } return out - } type dateMatchCandidate struct { @@ -136,7 +135,7 @@ func dateWithoutSepMatch(password string) []match.Match { return matches } -//TODO Has issues with 6 digit dates +// TODO Has issues with 6 digit dates func dateWithoutSepMatchHelper(password string) (matches []match.DateMatch) { for _, v := range dateWithOutSepMatch.FindAllString(password, len(password)) { i := strings.Index(password, v) @@ -146,17 +145,17 @@ func dateWithoutSepMatchHelper(password string) (matches []match.DateMatch) { var candidatesRoundOne []dateMatchCandidate if length <= 6 { - //2-digit year prefix + // 2-digit year prefix candidatesRoundOne = append(candidatesRoundOne, buildDateMatchCandidate(v[2:], v[0:2], i, j)) - //2-digityear suffix + // 2-digityear suffix candidatesRoundOne = append(candidatesRoundOne, buildDateMatchCandidate(v[0:lastIndex-2], v[lastIndex-2:], i, j)) } if length >= 6 { - //4-digit year prefix + // 4-digit year prefix candidatesRoundOne = append(candidatesRoundOne, buildDateMatchCandidate(v[4:], v[0:4], i, j)) - //4-digit year sufix + // 4-digit year sufix candidatesRoundOne = append(candidatesRoundOne, buildDateMatchCandidate(v[0:lastIndex-3], v[lastIndex-3:], i, j)) } @@ -179,7 +178,6 @@ func dateWithoutSepMatchHelper(password string) (matches []match.DateMatch) { } intMonth, err := strconv.ParseInt(candidate.Month, 10, 16) - if err != nil { continue } @@ -204,6 +202,5 @@ func buildDateMatchCandidate(dayMonth, year string, i, j int) dateMatchCandidate } func buildDateMatchCandidateTwo(day, month string, year string, i, j int) dateMatchCandidateTwo { - return dateMatchCandidateTwo{Day: day, Month: month, Year: year, I: i, J: j} } diff --git a/vendor/github.com/nbutton23/zxcvbn-go/matching/dictionaryMatch.go b/vendor/github.com/ccojocar/zxcvbn-go/matching/dictionaryMatch.go index 4ddb2c3b0..d0d450188 100644 --- a/vendor/github.com/nbutton23/zxcvbn-go/matching/dictionaryMatch.go +++ b/vendor/github.com/ccojocar/zxcvbn-go/matching/dictionaryMatch.go @@ -3,8 +3,8 @@ package matching import ( "strings" - "github.com/nbutton23/zxcvbn-go/entropy" - "github.com/nbutton23/zxcvbn-go/match" + "github.com/ccojocar/zxcvbn-go/entropy" + "github.com/ccojocar/zxcvbn-go/match" ) func buildDictMatcher(dictName string, rankedDict map[string]int) func(password string) []match.Match { @@ -15,7 +15,6 @@ func buildDictMatcher(dictName string, rankedDict map[string]int) func(password } return matches } - } func dictionaryMatch(password string, dictionaryName string, rankedDict map[string]int) []match.Match { @@ -29,7 +28,8 @@ func dictionaryMatch(password string, dictionaryName string, rankedDict map[stri for j := i; j < length; j++ { word := pwLowerRunes[i : j+1] if val, ok := rankedDict[string(word)]; ok { - matchDic := match.Match{Pattern: "dictionary", + matchDic := match.Match{ + Pattern: "dictionary", DictionaryName: dictionaryName, I: i, J: j, @@ -46,7 +46,6 @@ func dictionaryMatch(password string, dictionaryName string, rankedDict map[stri } func buildRankedDict(unrankedList []string) map[string]int { - result := make(map[string]int) for i, v := range unrankedList { diff --git a/vendor/github.com/nbutton23/zxcvbn-go/matching/leet.go b/vendor/github.com/ccojocar/zxcvbn-go/matching/leet.go index 610f1973f..1f303aa6e 100644 --- a/vendor/github.com/nbutton23/zxcvbn-go/matching/leet.go +++ b/vendor/github.com/ccojocar/zxcvbn-go/matching/leet.go @@ -3,14 +3,14 @@ package matching import ( "strings" - "github.com/nbutton23/zxcvbn-go/entropy" - "github.com/nbutton23/zxcvbn-go/match" + "github.com/ccojocar/zxcvbn-go/entropy" + "github.com/ccojocar/zxcvbn-go/match" ) // L33TMatcherName id const L33TMatcherName = "l33t" -//FilterL33tMatcher can be pass to zxcvbn-go.PasswordStrength to skip that matcher +// FilterL33tMatcher can be pass to zxcvbn-go.PasswordStrength to skip that matcher func FilterL33tMatcher(m match.Matcher) bool { return m.ID == L33TMatcherName } @@ -105,7 +105,7 @@ func createListOfMapsWithoutConflicts(table map[string][]string) []map[string][] return result } -// This function retrieves the list of values that appear for one or more keys. This is usefull to +// This function retrieves the list of values that appear for one or more keys. This is useful to // know which l33t chars can represent more than one letter. func retrieveConflictsListFromTable(table map[string][]string) []string { result := []string{} @@ -128,7 +128,7 @@ func retrieveConflictsListFromTable(table map[string][]string) []string { } // This function aims to create different maps for a given char if this char represents a conflict. -// If the specified char is not a conflit one, the same map will be returned. In scenarios which +// If the specified char is not a conflict one, the same map will be returned. In scenarios which // the provided char can not be found on map, an empty list will be returned. This function was // designed to be used on conflicts situations. func createDifferentMapsForLeetChar(table map[string][]string, leetChar string) []map[string][]string { @@ -158,7 +158,7 @@ func retrieveListOfKeysWithSpecificValueFromTable(table map[string][]string, val return result } -// This function returns a lsit of substitution map from a given table. Each map in the result will +// This function returns a list of substitution map from a given table. Each map in the result will // provide only one representation for each value. As an example, if the provided map contains the // values "@" and "4" in the possibilities to represent "a", two maps will be created where one // will contain "a" mapping to "@" and the other one will provide "a" mapping to "4". diff --git a/vendor/github.com/nbutton23/zxcvbn-go/matching/matching.go b/vendor/github.com/ccojocar/zxcvbn-go/matching/matching.go index 4577db8a4..c6948067b 100644 --- a/vendor/github.com/nbutton23/zxcvbn-go/matching/matching.go +++ b/vendor/github.com/ccojocar/zxcvbn-go/matching/matching.go @@ -3,9 +3,9 @@ package matching import ( "sort" - "github.com/nbutton23/zxcvbn-go/adjacency" - "github.com/nbutton23/zxcvbn-go/frequency" - "github.com/nbutton23/zxcvbn-go/match" + "github.com/ccojocar/zxcvbn-go/adjacency" + "github.com/ccojocar/zxcvbn-go/frequency" + "github.com/ccojocar/zxcvbn-go/match" ) var ( @@ -23,8 +23,7 @@ func init() { // Omnimatch runs all matchers against the password func Omnimatch(password string, userInputs []string, filters ...func(match.Matcher) bool) (matches []match.Match) { - - //Can I run into the issue where nil is not equal to nil? + // Can I run into the issue where nil is not equal to nil? if dictionaryMatchers == nil || adjacencyGraphs == nil { loadFrequencyList() } @@ -51,7 +50,6 @@ func Omnimatch(password string, userInputs []string, filters ...func(match.Match } func loadFrequencyList() { - for n, list := range frequency.Lists { dictionaryMatchers = append(dictionaryMatchers, match.Matcher{MatchingFunc: buildDictMatcher(n, buildRankedDict(list.List)), ID: n}) } @@ -63,8 +61,8 @@ func loadFrequencyList() { adjacencyGraphs = append(adjacencyGraphs, adjacency.GraphMap["keypad"]) adjacencyGraphs = append(adjacencyGraphs, adjacency.GraphMap["macKeypad"]) - //l33tFilePath, _ := filepath.Abs("adjacency/L33t.json") - //L33T_TABLE = adjacency.GetAdjancencyGraphFromFile(l33tFilePath, "l33t") + // l33tFilePath, _ := filepath.Abs("adjacency/L33t.json") + // L33T_TABLE = adjacency.GetAdjancencyGraphFromFile(l33tFilePath, "l33t") sequences = make(map[string]string) sequences["lower"] = "abcdefghijklmnopqrstuvwxyz" @@ -78,5 +76,4 @@ func loadFrequencyList() { matchers = append(matchers, match.Matcher{MatchingFunc: l33tMatch, ID: L33TMatcherName}) matchers = append(matchers, match.Matcher{MatchingFunc: dateSepMatcher, ID: dateSepMatcherName}) matchers = append(matchers, match.Matcher{MatchingFunc: dateWithoutSepMatch, ID: dateWithOutSepMatcherName}) - } diff --git a/vendor/github.com/nbutton23/zxcvbn-go/matching/repeatMatch.go b/vendor/github.com/ccojocar/zxcvbn-go/matching/repeatMatch.go index a93e45935..d52ba4254 100644 --- a/vendor/github.com/nbutton23/zxcvbn-go/matching/repeatMatch.go +++ b/vendor/github.com/ccojocar/zxcvbn-go/matching/repeatMatch.go @@ -3,13 +3,13 @@ package matching import ( "strings" - "github.com/nbutton23/zxcvbn-go/entropy" - "github.com/nbutton23/zxcvbn-go/match" + "github.com/ccojocar/zxcvbn-go/entropy" + "github.com/ccojocar/zxcvbn-go/match" ) const repeatMatcherName = "REPEAT" -//FilterRepeatMatcher can be pass to zxcvbn-go.PasswordStrength to skip that matcher +// FilterRepeatMatcher can be pass to zxcvbn-go.PasswordStrength to skip that matcher func FilterRepeatMatcher(m match.Matcher) bool { return m.ID == repeatMatcherName } @@ -17,7 +17,7 @@ func FilterRepeatMatcher(m match.Matcher) bool { func repeatMatch(password string) []match.Match { var matches []match.Match - //Loop through password. if current == prev currentStreak++ else if currentStreak > 2 {buildMatch; currentStreak = 1} prev = current + // Loop through password. if current == prev currentStreak++ else if currentStreak > 2 {buildMatch; currentStreak = 1} prev = current var current, prev string currentStreak := 1 var i int @@ -29,9 +29,8 @@ func repeatMatch(password string) []match.Match { continue } - if strings.ToLower(current) == strings.ToLower(prev) { + if strings.EqualFold(current, prev) { currentStreak++ - } else if currentStreak > 2 { iPos := i - currentStreak jPos := i - 1 @@ -40,7 +39,8 @@ func repeatMatch(password string) []match.Match { I: iPos, J: jPos, Token: password[iPos : jPos+1], - DictionaryName: prev} + DictionaryName: prev, + } matchRepeat.Entropy = entropy.RepeatEntropy(matchRepeat) matches = append(matches, matchRepeat) currentStreak = 1 @@ -59,7 +59,8 @@ func repeatMatch(password string) []match.Match { I: iPos, J: jPos, Token: password[iPos : jPos+1], - DictionaryName: prev} + DictionaryName: prev, + } matchRepeat.Entropy = entropy.RepeatEntropy(matchRepeat) matches = append(matches, matchRepeat) } diff --git a/vendor/github.com/nbutton23/zxcvbn-go/matching/sequenceMatch.go b/vendor/github.com/ccojocar/zxcvbn-go/matching/sequenceMatch.go index e0ed05229..697194583 100644 --- a/vendor/github.com/nbutton23/zxcvbn-go/matching/sequenceMatch.go +++ b/vendor/github.com/ccojocar/zxcvbn-go/matching/sequenceMatch.go @@ -3,13 +3,13 @@ package matching import ( "strings" - "github.com/nbutton23/zxcvbn-go/entropy" - "github.com/nbutton23/zxcvbn-go/match" + "github.com/ccojocar/zxcvbn-go/entropy" + "github.com/ccojocar/zxcvbn-go/match" ) const sequenceMatcherName = "SEQ" -//FilterSequenceMatcher can be pass to zxcvbn-go.PasswordStrength to skip that matcher +// FilterSequenceMatcher can be pass to zxcvbn-go.PasswordStrength to skip that matcher func FilterSequenceMatcher(m match.Matcher) bool { return m.ID == sequenceMatcherName } @@ -64,10 +64,8 @@ func sequenceMatch(password string) []match.Match { matches = append(matches, matchSequence) } break - } else { - j++ } - + j++ } } i = j diff --git a/vendor/github.com/nbutton23/zxcvbn-go/matching/spatialMatch.go b/vendor/github.com/ccojocar/zxcvbn-go/matching/spatialMatch.go index fd858f5d1..101ccea5e 100644 --- a/vendor/github.com/nbutton23/zxcvbn-go/matching/spatialMatch.go +++ b/vendor/github.com/ccojocar/zxcvbn-go/matching/spatialMatch.go @@ -3,14 +3,14 @@ package matching import ( "strings" - "github.com/nbutton23/zxcvbn-go/adjacency" - "github.com/nbutton23/zxcvbn-go/entropy" - "github.com/nbutton23/zxcvbn-go/match" + "github.com/ccojocar/zxcvbn-go/adjacency" + "github.com/ccojocar/zxcvbn-go/entropy" + "github.com/ccojocar/zxcvbn-go/match" ) const spatialMatcherName = "SPATIAL" -//FilterSpatialMatcher can be pass to zxcvbn-go.PasswordStrength to skip that matcher +// FilterSpatialMatcher can be pass to zxcvbn-go.PasswordStrength to skip that matcher func FilterSpatialMatcher(m match.Matcher) bool { return m.ID == spatialMatcherName } @@ -25,39 +25,38 @@ func spatialMatch(password string) (matches []match.Match) { } func spatialMatchHelper(password string, graph adjacency.Graph) (matches []match.Match) { - for i := 0; i < len(password)-1; { j := i + 1 - lastDirection := -99 //an int that it should never be! + lastDirection := -99 // an int that it should never be! turns := 0 shiftedCount := 0 for { prevChar := password[j-1] found := false - foundDirection := -1 + var foundDirection int curDirection := -1 - //My graphs seem to be wrong. . . and where the hell is qwerty + // My graphs seem to be wrong. . . and where the hell is qwerty adjacents := graph.Graph[string(prevChar)] - //Consider growing pattern by one character if j hasn't gone over the edge + // Consider growing pattern by one character if j hasn't gone over the edge if j < len(password) { curChar := password[j] for _, adj := range adjacents { curDirection++ - if strings.Index(adj, string(curChar)) != -1 { + if strings.Contains(adj, string(curChar)) { found = true foundDirection = curDirection if strings.Index(adj, string(curChar)) == 1 { - //index 1 in the adjacency means the key is shifted, 0 means unshifted: A vs a, % vs 5, etc. - //for example, 'q' is adjacent to the entry '2@'. @ is shifted w/ index 1, 2 is unshifted. + // index 1 in the adjacency means the key is shifted, 0 means unshifted: A vs a, % vs 5, etc. + // for example, 'q' is adjacent to the entry '2@'. @ is shifted w/ index 1, 2 is unshifted. shiftedCount++ } if lastDirection != foundDirection { - //adding a turn is correct even in the initial case when last_direction is null: - //every spatial pattern starts with a turn. + // adding a turn is correct even in the initial case when last_direction is null: + // every spatial pattern starts with a turn. turns++ lastDirection = foundDirection } @@ -66,12 +65,12 @@ func spatialMatchHelper(password string, graph adjacency.Graph) (matches []match } } - //if the current pattern continued, extend j and try to grow again + // if the current pattern continued, extend j and try to grow again if found { j++ } else { - //otherwise push the pattern discovered so far, if any... - //don't consider length 1 or 2 chains. + // otherwise push the pattern discovered so far, if any... + // don't consider length 1 or 2 chains. if j-i > 2 { matchSpc := match.Match{Pattern: "spatial", I: i, J: j - 1, Token: password[i:j], DictionaryName: graph.Name} matchSpc.Entropy = entropy.SpatialEntropy(matchSpc, turns, shiftedCount) diff --git a/vendor/github.com/nbutton23/zxcvbn-go/scoring/scoring.go b/vendor/github.com/ccojocar/zxcvbn-go/scoring/scoring.go index 4f68a6dca..dbe331884 100644 --- a/vendor/github.com/nbutton23/zxcvbn-go/scoring/scoring.go +++ b/vendor/github.com/ccojocar/zxcvbn-go/scoring/scoring.go @@ -2,11 +2,12 @@ package scoring import ( "fmt" - "github.com/nbutton23/zxcvbn-go/entropy" - "github.com/nbutton23/zxcvbn-go/match" - "github.com/nbutton23/zxcvbn-go/utils/math" "math" "sort" + + "github.com/ccojocar/zxcvbn-go/entropy" + "github.com/ccojocar/zxcvbn-go/match" + zxcvbnmath "github.com/ccojocar/zxcvbn-go/utils/math" ) const ( @@ -15,7 +16,7 @@ const ( //adjust for your site accordingly if you use another hash function, possibly by //several orders of magnitude! singleGuess float64 = 0.010 - numAttackers float64 = 100 //Cores used to make guesses + numAttackers float64 = 100 // Cores used to make guesses secondsPerGuess float64 = singleGuess / numAttackers ) @@ -33,11 +34,11 @@ type MinEntropyMatch struct { /* MinimumEntropyMatchSequence returns the minimum entropy - Takes a list of overlapping matches, returns the non-overlapping sublist with - minimum entropy. O(nm) dp alg for length-n password with m candidate matches. + Takes a list of overlapping matches, returns the non-overlapping sublist with + minimum entropy. O(nm) dp alg for length-n password with m candidate matches. */ func MinimumEntropyMatchSequence(password string, matches []match.Match) MinEntropyMatch { - bruteforceCardinality := float64(entropy.CalcBruteForceCardinality(password)) + bruteforceCardinality := entropy.CalcBruteForceCardinality(password) upToK := make([]float64, len(password)) backPointers := make([]match.Match, len(password)) @@ -50,7 +51,7 @@ func MinimumEntropyMatchSequence(password string, matches []match.Match) MinEntr } i, j := match.I, match.J - //see if best entropy up to i-1 + entropy of match is less that current min at j + // see if best entropy up to i-1 + entropy of match is less that current min at j upTo := get(upToK, i-1) candidateEntropy := upTo + match.Entropy @@ -62,7 +63,7 @@ func MinimumEntropyMatchSequence(password string, matches []match.Match) MinEntr } } - //walk backwards and decode the best sequence + // walk backwards and decode the best sequence var matchSequence []match.Match passwordLen := len(password) passwordLen-- @@ -80,12 +81,13 @@ func MinimumEntropyMatchSequence(password string, matches []match.Match) MinEntr sort.Sort(match.Matches(matchSequence)) makeBruteForceMatch := func(i, j int) match.Match { - return match.Match{Pattern: "bruteforce", + return match.Match{ + Pattern: "bruteforce", I: i, J: j, Token: password[i : j+1], - Entropy: math.Log2(math.Pow(bruteforceCardinality, float64(j-i)))} - + Entropy: math.Log2(math.Pow(bruteforceCardinality, float64(j-i))), + } } k := 0 @@ -110,14 +112,16 @@ func MinimumEntropyMatchSequence(password string, matches []match.Match) MinEntr } crackTime := roundToXDigits(entropyToCrackTime(minEntropy), 3) - return MinEntropyMatch{Password: password, + return MinEntropyMatch{ + Password: password, Entropy: roundToXDigits(minEntropy, 3), MatchSequence: matchSequenceCopy, CrackTime: crackTime, CrackTimeDisplay: displayTime(crackTime), - Score: crackTimeToScore(crackTime)} - + Score: crackTimeToScore(crackTime), + } } + func get(a []float64, i int) float64 { if i < 0 || i >= len(a) { return float64(0) diff --git a/vendor/github.com/nbutton23/zxcvbn-go/utils/math/mathutils.go b/vendor/github.com/ccojocar/zxcvbn-go/utils/math/mathutils.go index 1b989d194..1b989d194 100644 --- a/vendor/github.com/nbutton23/zxcvbn-go/utils/math/mathutils.go +++ b/vendor/github.com/ccojocar/zxcvbn-go/utils/math/mathutils.go diff --git a/vendor/github.com/nbutton23/zxcvbn-go/zxcvbn.go b/vendor/github.com/ccojocar/zxcvbn-go/zxcvbn.go index 9c34b1c8c..f3dc19e4c 100644 --- a/vendor/github.com/nbutton23/zxcvbn-go/zxcvbn.go +++ b/vendor/github.com/ccojocar/zxcvbn-go/zxcvbn.go @@ -3,10 +3,10 @@ package zxcvbn import ( "time" - "github.com/nbutton23/zxcvbn-go/match" - "github.com/nbutton23/zxcvbn-go/matching" - "github.com/nbutton23/zxcvbn-go/scoring" - "github.com/nbutton23/zxcvbn-go/utils/math" + "github.com/ccojocar/zxcvbn-go/match" + "github.com/ccojocar/zxcvbn-go/matching" + "github.com/ccojocar/zxcvbn-go/scoring" + zxcvbnmath "github.com/ccojocar/zxcvbn-go/utils/math" ) // PasswordStrength takes a password, userInputs and optional filters and returns a MinEntropyMatch diff --git a/vendor/github.com/golangci/golangci-lint/pkg/golinters/govet.go b/vendor/github.com/golangci/golangci-lint/pkg/golinters/govet.go index 6cd4c9b66..5a1309cd0 100644 --- a/vendor/github.com/golangci/golangci-lint/pkg/golinters/govet.go +++ b/vendor/github.com/golangci/golangci-lint/pkg/golinters/govet.go @@ -15,6 +15,7 @@ import ( _ "golang.org/x/tools/go/analysis/passes/ctrlflow" // unused, internal analyzer "golang.org/x/tools/go/analysis/passes/deepequalerrors" "golang.org/x/tools/go/analysis/passes/defers" + "golang.org/x/tools/go/analysis/passes/directive" "golang.org/x/tools/go/analysis/passes/errorsas" "golang.org/x/tools/go/analysis/passes/fieldalignment" "golang.org/x/tools/go/analysis/passes/findcall" @@ -32,6 +33,7 @@ import ( "golang.org/x/tools/go/analysis/passes/shadow" "golang.org/x/tools/go/analysis/passes/shift" "golang.org/x/tools/go/analysis/passes/sigchanyzer" + "golang.org/x/tools/go/analysis/passes/slog" "golang.org/x/tools/go/analysis/passes/sortslice" "golang.org/x/tools/go/analysis/passes/stdmethods" "golang.org/x/tools/go/analysis/passes/stringintconv" @@ -62,6 +64,7 @@ var ( copylock.Analyzer, deepequalerrors.Analyzer, defers.Analyzer, + directive.Analyzer, errorsas.Analyzer, fieldalignment.Analyzer, findcall.Analyzer, @@ -77,6 +80,7 @@ var ( shadow.Analyzer, shift.Analyzer, sigchanyzer.Analyzer, + slog.Analyzer, sortslice.Analyzer, stdmethods.Analyzer, stringintconv.Analyzer, @@ -91,7 +95,7 @@ var ( unusedwrite.Analyzer, } - // https://github.com/golang/go/blob/9f834a559c9ed6cdf883e29b36e21e5f956df74f/src/cmd/vet/main.go#L46-L76 + // https://github.com/golang/go/blob/c19c4c566c63818dfd059b352e52c4710eecf14d/src/cmd/vet/main.go#L47-L78 defaultAnalyzers = []*analysis.Analyzer{ asmdecl.Analyzer, assign.Analyzer, @@ -101,6 +105,7 @@ var ( cgocall.Analyzer, composite.Analyzer, copylock.Analyzer, + directive.Analyzer, errorsas.Analyzer, framepointer.Analyzer, httpresponse.Analyzer, @@ -111,6 +116,7 @@ var ( printf.Analyzer, shift.Analyzer, sigchanyzer.Analyzer, + slog.Analyzer, stdmethods.Analyzer, stringintconv.Analyzer, structtag.Analyzer, diff --git a/vendor/github.com/nbutton23/zxcvbn-go/.gitignore b/vendor/github.com/nbutton23/zxcvbn-go/.gitignore deleted file mode 100644 index 4bff1a28e..000000000 --- a/vendor/github.com/nbutton23/zxcvbn-go/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -zxcvbn -debug.test diff --git a/vendor/github.com/nbutton23/zxcvbn-go/Makefile b/vendor/github.com/nbutton23/zxcvbn-go/Makefile deleted file mode 100644 index 6aa13e006..000000000 --- a/vendor/github.com/nbutton23/zxcvbn-go/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -PKG_LIST = $$( go list ./... | grep -v /vendor/ | grep -v "zxcvbn-go/data" ) - -.DEFAULT_GOAL := help - -.PHONY: help -help: - @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' - -.PHONY: test -test: ## Run `go test {Package list}` on the packages - go test $(PKG_LIST) - -.PHONY: lint -lint: ## Run `golint {Package list}` - golint $(PKG_LIST)
\ No newline at end of file diff --git a/vendor/github.com/nunnatsa/ginkgolinter/README.md b/vendor/github.com/nunnatsa/ginkgolinter/README.md index 3edf065c2..4193be63d 100644 --- a/vendor/github.com/nunnatsa/ginkgolinter/README.md +++ b/vendor/github.com/nunnatsa/ginkgolinter/README.md @@ -153,24 +153,35 @@ The linter will not suggest a fix for this warning. This rule cannot be suppressed. -### Focus Container Found [BUG] -This rule finds ginkgo focus containers in the code. +### Focus Container / Focus individual spec found [BUG] +This rule finds ginkgo focus containers, or the `Focus` individual spec in the code. -ginkgo supports the `FDescribe`, `FContext`, `FWhen` and `FIt` containers to allow the developer to focus +ginkgo supports the `FDescribe`, `FContext`, `FWhen`, `FIt`, `FDescribeTable` and `FEntry` +containers to allow the developer to focus on a specific test or set of tests during test development or debug. -***This rule is disabled by default***. Use the `--forbid-focus-container=true` command line flag to enable it. - For example: ```go var _ = Describe("checking something", func() { - FIt("this test is the only one that will run", func(){ - ... - }) + FIt("this test is the only one that will run", func(){ + ... + }) +}) +``` +Alternatively, the `Focus` individual spec may be used for the same purpose, e.g. +```go +var _ = Describe("checking something", Focus, func() { + It("this test is the only one that will run", func(){ + ... + }) }) ``` -These container must not be part of the final source code, and should only be used locally by the developer. +These container, or the `Focus` spec, must not be part of the final source code, and should only be used locally by the developer. + +***This rule is disabled by default***. Use the `--forbid-focus-container=true` command line flag to enable it. + + ### Wrong Length Assertion [STYLE] The linter finds assertion of the golang built-in `len` function, with all kind of matchers, while there are already gomega matchers for these usecases; We want to assert the item, rather than its length. diff --git a/vendor/github.com/nunnatsa/ginkgolinter/ginkgo_linter.go b/vendor/github.com/nunnatsa/ginkgolinter/ginkgo_linter.go index 1635ce4b0..11cffaca5 100644 --- a/vendor/github.com/nunnatsa/ginkgolinter/ginkgo_linter.go +++ b/vendor/github.com/nunnatsa/ginkgolinter/ginkgo_linter.go @@ -37,6 +37,7 @@ const ( missingAssertionMessage = linterName + `: %q: missing assertion method. Expected "Should()", "To()", "ShouldNot()", "ToNot()" or "NotTo()"` missingAsyncAssertionMessage = linterName + `: %q: missing assertion method. Expected "Should()" or "ShouldNot()"` focusContainerFound = linterName + ": Focus container found. This is used only for local debug and should not be part of the actual source code, consider to replace with %q" + focusSpecFound = linterName + ": Focus spec found. This is used only for local debug and should not be part of the actual source code, consider to remove it" ) const ( // gomega matchers beEmpty = "BeEmpty" @@ -232,12 +233,27 @@ func (l *ginkgoLinter) run(pass *analysis.Pass) (interface{}, error) { } func checkFocusContainer(pass *analysis.Pass, ginkgoHndlr ginkgohandler.Handler, exp *ast.CallExpr) bool { + foundFocus := false isFocus, id := ginkgoHndlr.GetFocusContainerName(exp) if isFocus { reportNewName(pass, id, id.Name[1:], focusContainerFound, id.Name) - return true + foundFocus = true } - return false + + if id != nil && ginkgohandler.IsContainer(id) { + for _, arg := range exp.Args { + if ginkgoHndlr.IsFocusSpec(arg) { + reportNoFix(pass, arg.Pos(), focusSpecFound) + foundFocus = true + } else if callExp, ok := arg.(*ast.CallExpr); ok { + if checkFocusContainer(pass, ginkgoHndlr, callExp) { // handle table entries + foundFocus = true + } + } + } + } + + return foundFocus } func checkExpression(pass *analysis.Pass, config types.Config, assertionExp *ast.CallExpr, actualExpr *ast.CallExpr, handler gomegahandler.Handler) bool { diff --git a/vendor/github.com/nunnatsa/ginkgolinter/ginkgohandler/handler.go b/vendor/github.com/nunnatsa/ginkgolinter/ginkgohandler/handler.go index 87703a944..c0829c469 100644 --- a/vendor/github.com/nunnatsa/ginkgolinter/ginkgohandler/handler.go +++ b/vendor/github.com/nunnatsa/ginkgolinter/ginkgohandler/handler.go @@ -4,16 +4,24 @@ import ( "go/ast" ) +const ( + importPath = `"github.com/onsi/ginkgo"` + importPathV2 = `"github.com/onsi/ginkgo/v2"` + + focusSpec = "Focus" +) + // Handler provide different handling, depend on the way ginkgo was imported, whether // in imported with "." name, custom name or without any name. type Handler interface { GetFocusContainerName(*ast.CallExpr) (bool, *ast.Ident) + IsFocusSpec(ident ast.Expr) bool } // GetGinkgoHandler returns a ginkgor handler according to the way ginkgo was imported in the specific file func GetGinkgoHandler(file *ast.File) Handler { for _, imp := range file.Imports { - if imp.Path.Value != `"github.com/onsi/ginkgo"` && imp.Path.Value != `"github.com/onsi/ginkgo/v2"` { + if imp.Path.Value != importPath && imp.Path.Value != importPathV2 { continue } @@ -41,6 +49,11 @@ func (h dotHandler) GetFocusContainerName(exp *ast.CallExpr) (bool, *ast.Ident) return false, nil } +func (h dotHandler) IsFocusSpec(exp ast.Expr) bool { + id, ok := exp.(*ast.Ident) + return ok && id.Name == focusSpec +} + // nameHandler is used when importing ginkgo without name; i.e. // import "github.com/onsi/ginkgo" // @@ -57,10 +70,28 @@ func (h nameHandler) GetFocusContainerName(exp *ast.CallExpr) (bool, *ast.Ident) return false, nil } +func (h nameHandler) IsFocusSpec(exp ast.Expr) bool { + if selExp, ok := exp.(*ast.SelectorExpr); ok { + if x, ok := selExp.X.(*ast.Ident); ok && x.Name == string(h) { + return selExp.Sel.Name == focusSpec + } + } + + return false +} + func isFocusContainer(name string) bool { switch name { - case "FDescribe", "FContext", "FWhen", "FIt": + case "FDescribe", "FContext", "FWhen", "FIt", "FDescribeTable", "FEntry": return true } return false } + +func IsContainer(id *ast.Ident) bool { + switch id.Name { + case "It", "When", "Context", "Describe", "DescribeTable", "Entry": + return true + } + return isFocusContainer(id.Name) +} diff --git a/vendor/github.com/polyfloyd/go-errorlint/errorlint/allowed.go b/vendor/github.com/polyfloyd/go-errorlint/errorlint/allowed.go index d4274b8a7..be4debf9b 100644 --- a/vendor/github.com/polyfloyd/go-errorlint/errorlint/allowed.go +++ b/vendor/github.com/polyfloyd/go-errorlint/errorlint/allowed.go @@ -3,6 +3,7 @@ package errorlint import ( "fmt" "go/ast" + "strings" ) var allowedErrors = []struct { @@ -34,10 +35,10 @@ var allowedErrors = []struct { {err: "io.EOF", fun: "(*bytes.Reader).ReadRune"}, {err: "io.EOF", fun: "(*bytes.Reader).ReadString"}, // pkg/database/sql - {err: "sql.ErrNoRows", fun: "(*database/sql.Row).Scan"}, + {err: "database/sql.ErrNoRows", fun: "(*database/sql.Row).Scan"}, // pkg/debug/elf - {err: "io.EOF", fun: "elf.Open"}, - {err: "io.EOF", fun: "elf.NewFile"}, + {err: "io.EOF", fun: "debug/elf.Open"}, + {err: "io.EOF", fun: "debug/elf.NewFile"}, // pkg/io {err: "io.EOF", fun: "(io.Reader).Read"}, {err: "io.EOF", fun: "(io.ReaderAt).ReadAt"}, @@ -50,14 +51,14 @@ var allowedErrors = []struct { {err: "io.EOF", fun: "io.ReadFull"}, {err: "io.ErrUnexpectedEOF", fun: "io.ReadFull"}, // pkg/net/http - {err: "http.ErrServerClosed", fun: "(*net/http.Server).ListenAndServe"}, - {err: "http.ErrServerClosed", fun: "(*net/http.Server).ListenAndServeTLS"}, - {err: "http.ErrServerClosed", fun: "(*net/http.Server).Serve"}, - {err: "http.ErrServerClosed", fun: "(*net/http.Server).ServeTLS"}, - {err: "http.ErrServerClosed", fun: "http.ListenAndServe"}, - {err: "http.ErrServerClosed", fun: "http.ListenAndServeTLS"}, - {err: "http.ErrServerClosed", fun: "http.Serve"}, - {err: "http.ErrServerClosed", fun: "http.ServeTLS"}, + {err: "net/http.ErrServerClosed", fun: "(*net/http.Server).ListenAndServe"}, + {err: "net/http.ErrServerClosed", fun: "(*net/http.Server).ListenAndServeTLS"}, + {err: "net/http.ErrServerClosed", fun: "(*net/http.Server).Serve"}, + {err: "net/http.ErrServerClosed", fun: "(*net/http.Server).ServeTLS"}, + {err: "net/http.ErrServerClosed", fun: "net/http.ListenAndServe"}, + {err: "net/http.ErrServerClosed", fun: "net/http.ListenAndServeTLS"}, + {err: "net/http.ErrServerClosed", fun: "net/http.Serve"}, + {err: "net/http.ErrServerClosed", fun: "net/http.ServeTLS"}, // pkg/os {err: "io.EOF", fun: "(*os.File).Read"}, {err: "io.EOF", fun: "(*os.File).ReadAt"}, @@ -71,7 +72,21 @@ var allowedErrors = []struct { {err: "io.EOF", fun: "(*strings.Reader).ReadRune"}, } +var allowedErrorWildcards = []struct { + err string + fun string +}{ + // golang.org/x/sys/unix + {err: "golang.org/x/sys/unix.E", fun: "golang.org/x/sys/unix."}, +} + func isAllowedErrAndFunc(err, fun string) bool { + for _, allow := range allowedErrorWildcards { + if strings.HasPrefix(fun, allow.fun) && strings.HasPrefix(err, allow.err) { + return true + } + } + for _, allow := range allowedErrors { if allow.fun == fun && allow.err == err { return true @@ -80,7 +95,7 @@ func isAllowedErrAndFunc(err, fun string) bool { return false } -func isAllowedErrorComparison(info *TypesInfoExt, binExpr *ast.BinaryExpr) bool { +func isAllowedErrorComparison(pass *TypesInfoExt, binExpr *ast.BinaryExpr) bool { var errName string // `<package>.<name>`, e.g. `io.EOF` var callExprs []*ast.CallExpr @@ -91,11 +106,11 @@ func isAllowedErrorComparison(info *TypesInfoExt, binExpr *ast.BinaryExpr) bool case *ast.SelectorExpr: // A selector which we assume refers to a staticaly declared error // in a package. - errName = selectorToString(t) + errName = selectorToString(pass, t) case *ast.Ident: // Identifier, most likely to be the `err` variable or whatever // produces it. - callExprs = assigningCallExprs(info, t) + callExprs = assigningCallExprs(pass, t) case *ast.CallExpr: callExprs = append(callExprs, t) } @@ -115,11 +130,11 @@ func isAllowedErrorComparison(info *TypesInfoExt, binExpr *ast.BinaryExpr) bool // allowed. return false } - if sel, ok := info.Selections[functionSelector]; ok { + if sel, ok := pass.TypesInfo.Selections[functionSelector]; ok { functionNames[i] = fmt.Sprintf("(%s).%s", sel.Recv(), sel.Obj().Name()) } else { // If there is no selection, assume it is a package. - functionNames[i] = selectorToString(callExpr.Fun.(*ast.SelectorExpr)) + functionNames[i] = selectorToString(pass, callExpr.Fun.(*ast.SelectorExpr)) } } @@ -134,7 +149,7 @@ func isAllowedErrorComparison(info *TypesInfoExt, binExpr *ast.BinaryExpr) bool // assigningCallExprs finds all *ast.CallExpr nodes that are part of an // *ast.AssignStmt that assign to the subject identifier. -func assigningCallExprs(info *TypesInfoExt, subject *ast.Ident) []*ast.CallExpr { +func assigningCallExprs(pass *TypesInfoExt, subject *ast.Ident) []*ast.CallExpr { if subject.Obj == nil { return nil } @@ -142,9 +157,9 @@ func assigningCallExprs(info *TypesInfoExt, subject *ast.Ident) []*ast.CallExpr // Find other identifiers that reference this same object. Make sure to // exclude the subject identifier as it will cause an infinite recursion // and is being used in a read operation anyway. - sobj := info.ObjectOf(subject) + sobj := pass.TypesInfo.ObjectOf(subject) identifiers := []*ast.Ident{} - for _, ident := range info.IdentifiersForObject[sobj] { + for _, ident := range pass.IdentifiersForObject[sobj] { if subject.Pos() != ident.Pos() { identifiers = append(identifiers, ident) } @@ -153,7 +168,7 @@ func assigningCallExprs(info *TypesInfoExt, subject *ast.Ident) []*ast.CallExpr // Find out whether the identifiers are part of an assignment statement. var callExprs []*ast.CallExpr for _, ident := range identifiers { - parent := info.NodeParent[ident] + parent := pass.NodeParent[ident] switch declT := parent.(type) { case *ast.AssignStmt: // The identifier is LHS of an assignment. @@ -181,7 +196,7 @@ func assigningCallExprs(info *TypesInfoExt, subject *ast.Ident) []*ast.CallExpr continue } // The subject was the result of assigning from another identifier. - callExprs = append(callExprs, assigningCallExprs(info, assignT)...) + callExprs = append(callExprs, assigningCallExprs(pass, assignT)...) default: // TODO: inconclusive? } @@ -190,9 +205,7 @@ func assigningCallExprs(info *TypesInfoExt, subject *ast.Ident) []*ast.CallExpr return callExprs } -func selectorToString(selExpr *ast.SelectorExpr) string { - if ident, ok := selExpr.X.(*ast.Ident); ok { - return ident.Name + "." + selExpr.Sel.Name - } - return "" +func selectorToString(pass *TypesInfoExt, selExpr *ast.SelectorExpr) string { + o := pass.TypesInfo.Uses[selExpr.Sel] + return fmt.Sprintf("%s.%s", o.Pkg().Path(), o.Name()) } diff --git a/vendor/github.com/polyfloyd/go-errorlint/errorlint/analysis.go b/vendor/github.com/polyfloyd/go-errorlint/errorlint/analysis.go index c65c4ee62..f034913ea 100644 --- a/vendor/github.com/polyfloyd/go-errorlint/errorlint/analysis.go +++ b/vendor/github.com/polyfloyd/go-errorlint/errorlint/analysis.go @@ -35,13 +35,13 @@ func init() { func run(pass *analysis.Pass) (interface{}, error) { lints := []analysis.Diagnostic{} - extInfo := newTypesInfoExt(pass.TypesInfo) + extInfo := newTypesInfoExt(pass) if checkComparison { - l := LintErrorComparisons(pass.Fset, extInfo) + l := LintErrorComparisons(extInfo) lints = append(lints, l...) } if checkAsserts { - l := LintErrorTypeAssertions(pass.Fset, *pass.TypesInfo) + l := LintErrorTypeAssertions(pass.Fset, extInfo) lints = append(lints, l...) } if checkErrorf { @@ -57,7 +57,7 @@ func run(pass *analysis.Pass) (interface{}, error) { } type TypesInfoExt struct { - types.Info + *analysis.Pass // Maps AST nodes back to the node they are contained within. NodeParent map[ast.Node]ast.Node @@ -66,9 +66,9 @@ type TypesInfoExt struct { IdentifiersForObject map[types.Object][]*ast.Ident } -func newTypesInfoExt(info *types.Info) *TypesInfoExt { +func newTypesInfoExt(pass *analysis.Pass) *TypesInfoExt { nodeParent := map[ast.Node]ast.Node{} - for node := range info.Scopes { + for node := range pass.TypesInfo.Scopes { file, ok := node.(*ast.File) if !ok { continue @@ -86,15 +86,15 @@ func newTypesInfoExt(info *types.Info) *TypesInfoExt { } identifiersForObject := map[types.Object][]*ast.Ident{} - for node, obj := range info.Defs { + for node, obj := range pass.TypesInfo.Defs { identifiersForObject[obj] = append(identifiersForObject[obj], node) } - for node, obj := range info.Uses { + for node, obj := range pass.TypesInfo.Uses { identifiersForObject[obj] = append(identifiersForObject[obj], node) } return &TypesInfoExt{ - Info: *info, + Pass: pass, NodeParent: nodeParent, IdentifiersForObject: identifiersForObject, } diff --git a/vendor/github.com/polyfloyd/go-errorlint/errorlint/lint.go b/vendor/github.com/polyfloyd/go-errorlint/errorlint/lint.go index 920dc56e7..817cd6904 100644 --- a/vendor/github.com/polyfloyd/go-errorlint/errorlint/lint.go +++ b/vendor/github.com/polyfloyd/go-errorlint/errorlint/lint.go @@ -158,10 +158,10 @@ func isFmtErrorfCallExpr(info types.Info, expr ast.Expr) (*ast.CallExpr, bool) { return nil, false } -func LintErrorComparisons(fset *token.FileSet, info *TypesInfoExt) []analysis.Diagnostic { +func LintErrorComparisons(info *TypesInfoExt) []analysis.Diagnostic { lints := []analysis.Diagnostic{} - for expr := range info.Types { + for expr := range info.TypesInfo.Types { // Find == and != operations. binExpr, ok := expr.(*ast.BinaryExpr) if !ok { @@ -175,7 +175,7 @@ func LintErrorComparisons(fset *token.FileSet, info *TypesInfoExt) []analysis.Di continue } // Find comparisons of which one side is a of type error. - if !isErrorComparison(info.Info, binExpr) { + if !isErrorComparison(info.TypesInfo, binExpr) { continue } // Some errors that are returned from some functions are exempt. @@ -193,7 +193,7 @@ func LintErrorComparisons(fset *token.FileSet, info *TypesInfoExt) []analysis.Di }) } - for scope := range info.Scopes { + for scope := range info.TypesInfo.Scopes { // Find value switch blocks. switchStmt, ok := scope.(*ast.SwitchStmt) if !ok { @@ -203,7 +203,7 @@ func LintErrorComparisons(fset *token.FileSet, info *TypesInfoExt) []analysis.Di if switchStmt.Tag == nil { continue } - tagType := info.Types[switchStmt.Tag] + tagType := info.TypesInfo.Types[switchStmt.Tag] if tagType.Type.String() != "error" { continue } @@ -233,7 +233,7 @@ func isNilComparison(binExpr *ast.BinaryExpr) bool { return false } -func isErrorComparison(info types.Info, binExpr *ast.BinaryExpr) bool { +func isErrorComparison(info *types.Info, binExpr *ast.BinaryExpr) bool { tx := info.Types[binExpr.X] ty := info.Types[binExpr.Y] return tx.Type.String() == "error" || ty.Type.String() == "error" @@ -252,11 +252,11 @@ func isNodeInErrorIsFunc(info *TypesInfoExt, node ast.Node) bool { return false } // There should be 1 argument of type error. - if ii := funcDecl.Type.Params.List; len(ii) != 1 || info.Types[ii[0].Type].Type.String() != "error" { + if ii := funcDecl.Type.Params.List; len(ii) != 1 || info.TypesInfo.Types[ii[0].Type].Type.String() != "error" { return false } // The return type should be bool. - if ii := funcDecl.Type.Results.List; len(ii) != 1 || info.Types[ii[0].Type].Type.String() != "bool" { + if ii := funcDecl.Type.Results.List; len(ii) != 1 || info.TypesInfo.Types[ii[0].Type].Type.String() != "bool" { return false } @@ -288,10 +288,10 @@ func switchComparesNonNil(switchStmt *ast.SwitchStmt) bool { return false } -func LintErrorTypeAssertions(fset *token.FileSet, info types.Info) []analysis.Diagnostic { +func LintErrorTypeAssertions(fset *token.FileSet, info *TypesInfoExt) []analysis.Diagnostic { lints := []analysis.Diagnostic{} - for expr := range info.Types { + for expr := range info.TypesInfo.Types { // Find type assertions. typeAssert, ok := expr.(*ast.TypeAssertExpr) if !ok { @@ -299,7 +299,11 @@ func LintErrorTypeAssertions(fset *token.FileSet, info types.Info) []analysis.Di } // Find type assertions that operate on values of type error. - if !isErrorTypeAssertion(info, typeAssert) { + if !isErrorTypeAssertion(*info.TypesInfo, typeAssert) { + continue + } + + if isNodeInErrorIsFunc(info, typeAssert) { continue } @@ -309,7 +313,7 @@ func LintErrorTypeAssertions(fset *token.FileSet, info types.Info) []analysis.Di }) } - for scope := range info.Scopes { + for scope := range info.TypesInfo.Scopes { // Find type switches. typeSwitch, ok := scope.(*ast.TypeSwitchStmt) if !ok { @@ -326,7 +330,11 @@ func LintErrorTypeAssertions(fset *token.FileSet, info types.Info) []analysis.Di } // Check whether the type switch is on a value of type error. - if !isErrorTypeAssertion(info, typeAssert) { + if !isErrorTypeAssertion(*info.TypesInfo, typeAssert) { + continue + } + + if isNodeInErrorIsFunc(info, typeSwitch) { continue } diff --git a/vendor/github.com/sashamelentyev/usestdlibvars/pkg/analyzer/internal/mapping/mapping.go b/vendor/github.com/sashamelentyev/usestdlibvars/pkg/analyzer/internal/mapping/mapping.go index b081edea3..5bad23d28 100644 --- a/vendor/github.com/sashamelentyev/usestdlibvars/pkg/analyzer/internal/mapping/mapping.go +++ b/vendor/github.com/sashamelentyev/usestdlibvars/pkg/analyzer/internal/mapping/mapping.go @@ -161,6 +161,9 @@ var TimeLayout = map[string]string{ time.StampMilli: "time.StampMilli", time.StampMicro: "time.StampMicro", time.StampNano: "time.StampNano", + time.DateTime: "time.DateTime", + time.DateOnly: "time.DateOnly", + time.TimeOnly: "time.TimeOnly", } var SQLIsolationLevel = map[string]string{ diff --git a/vendor/github.com/securego/gosec/v2/.golangci.yml b/vendor/github.com/securego/gosec/v2/.golangci.yml index b12140a25..d6c5de7ba 100644 --- a/vendor/github.com/securego/gosec/v2/.golangci.yml +++ b/vendor/github.com/securego/gosec/v2/.golangci.yml @@ -2,7 +2,6 @@ linters: enable: - asciicheck - bodyclose - - depguard - dogsled - durationcheck - errcheck diff --git a/vendor/github.com/securego/gosec/v2/README.md b/vendor/github.com/securego/gosec/v2/README.md index 71e032d80..6c6d2982c 100644 --- a/vendor/github.com/securego/gosec/v2/README.md +++ b/vendor/github.com/securego/gosec/v2/README.md @@ -167,6 +167,7 @@ directory you can supply `./...` as the input argument. - G504: Import blocklist: net/http/cgi - G505: Import blocklist: crypto/sha1 - G601: Implicit memory aliasing of items from a range statement +- G602: Slice access out of bounds ### Retired rules diff --git a/vendor/github.com/securego/gosec/v2/action.yml b/vendor/github.com/securego/gosec/v2/action.yml index 0320f0c21..8e28c346d 100644 --- a/vendor/github.com/securego/gosec/v2/action.yml +++ b/vendor/github.com/securego/gosec/v2/action.yml @@ -10,7 +10,7 @@ inputs: runs: using: 'docker' - image: 'docker://securego/gosec:2.15.0' + image: 'docker://securego/gosec:2.16.0' args: - ${{ inputs.args }} diff --git a/vendor/github.com/securego/gosec/v2/analyzer.go b/vendor/github.com/securego/gosec/v2/analyzer.go index 830d338e4..023514b8a 100644 --- a/vendor/github.com/securego/gosec/v2/analyzer.go +++ b/vendor/github.com/securego/gosec/v2/analyzer.go @@ -59,7 +59,7 @@ var generatedCodePattern = regexp.MustCompile(`^// Code generated .* DO NOT EDIT // The Context is populated with data parsed from the source code as it is scanned. // It is passed through to all rule functions as they are called. Rules may use -// this data in conjunction withe the encountered AST node. +// this data in conjunction with the encountered AST node. type Context struct { FileSet *token.FileSet Comments ast.CommentMap @@ -449,10 +449,12 @@ func (gosec *Analyzer) ignore(n ast.Node) map[string]issue.SuppressionInfo { if groups, ok := gosec.context.Comments[n]; ok && !gosec.ignoreNosec { // Checks if an alternative for #nosec is set and, if not, uses the default. - noSecDefaultTag := "#nosec" + noSecDefaultTag := NoSecTag(string(Nosec)) noSecAlternativeTag, err := gosec.config.GetGlobal(NoSecAlternative) if err != nil { noSecAlternativeTag = noSecDefaultTag + } else { + noSecAlternativeTag = NoSecTag(noSecAlternativeTag) } for _, group := range groups { diff --git a/vendor/github.com/securego/gosec/v2/analyzers/ssrf.go b/vendor/github.com/securego/gosec/v2/analyzers/ssrf.go index a9dbd9500..70e0211f1 100644 --- a/vendor/github.com/securego/gosec/v2/analyzers/ssrf.go +++ b/vendor/github.com/securego/gosec/v2/analyzers/ssrf.go @@ -46,7 +46,7 @@ func runSSRF(pass *analysis.Pass) (interface{}, error) { if callee != nil { ssaResult.Logger.Printf("callee: %s\n", callee) return newIssue(pass.Analyzer.Name, - "not implemeted", + "not implemented", pass.Fset, instr.Call.Pos(), issue.Low, issue.High), nil } } diff --git a/vendor/github.com/securego/gosec/v2/analyzers/util.go b/vendor/github.com/securego/gosec/v2/analyzers/util.go index b090a3e45..f1bd867ae 100644 --- a/vendor/github.com/securego/gosec/v2/analyzers/util.go +++ b/vendor/github.com/securego/gosec/v2/analyzers/util.go @@ -28,7 +28,7 @@ import ( ) // SSAAnalyzerResult contains various information returned by the -// SSA analysis along with some configuraion +// SSA analysis along with some configuration type SSAAnalyzerResult struct { Config map[string]interface{} Logger *log.Logger @@ -42,7 +42,7 @@ func BuildDefaultAnalyzers() []*analysis.Analyzer { } } -// getSSAResult retrives the SSA result from analysis pass +// getSSAResult retrieves the SSA result from analysis pass func getSSAResult(pass *analysis.Pass) (*SSAAnalyzerResult, error) { result, ok := pass.ResultOf[buildssa.Analyzer] if !ok { diff --git a/vendor/github.com/securego/gosec/v2/config.go b/vendor/github.com/securego/gosec/v2/config.go index ca4cf2175..9cbb7a713 100644 --- a/vendor/github.com/securego/gosec/v2/config.go +++ b/vendor/github.com/securego/gosec/v2/config.go @@ -33,6 +33,11 @@ const ( SSA GlobalOption = "ssa" ) +// NoSecTag returns the tag used to disable gosec for a line of code. +func NoSecTag(tag string) string { + return fmt.Sprintf("%s%s", "#", tag) +} + // Config is used to provide configuration and customization to each of the rules. type Config map[string]interface{} diff --git a/vendor/github.com/securego/gosec/v2/helpers.go b/vendor/github.com/securego/gosec/v2/helpers.go index 08b7893eb..b4c23e5bb 100644 --- a/vendor/github.com/securego/gosec/v2/helpers.go +++ b/vendor/github.com/securego/gosec/v2/helpers.go @@ -96,11 +96,46 @@ func GetChar(n ast.Node) (byte, error) { return 0, fmt.Errorf("Unexpected AST node type: %T", n) } +// GetStringRecursive will recursively walk down a tree of *ast.BinaryExpr. It will then concat the results, and return. +// Unlike the other getters, it does _not_ raise an error for unknown ast.Node types. At the base, the recursion will hit a non-BinaryExpr type, +// either BasicLit or other, so it's not an error case. It will only error if `strconv.Unquote` errors. This matters, because there's +// currently functionality that relies on error values being returned by GetString if and when it hits a non-basiclit string node type, +// hence for cases where recursion is needed, we use this separate function, so that we can still be backwards compatbile. +// +// This was added to handle a SQL injection concatenation case where the injected value is infixed between two strings, not at the start or end. See example below +// +// Do note that this will omit non-string values. So for example, if you were to use this node: +// ```go +// q := "SELECT * FROM foo WHERE name = '" + os.Args[0] + "' AND 1=1" // will result in "SELECT * FROM foo WHERE ” AND 1=1" + +func GetStringRecursive(n ast.Node) (string, error) { + if node, ok := n.(*ast.BasicLit); ok && node.Kind == token.STRING { + return strconv.Unquote(node.Value) + } + + if expr, ok := n.(*ast.BinaryExpr); ok { + x, err := GetStringRecursive(expr.X) + if err != nil { + return "", err + } + + y, err := GetStringRecursive(expr.Y) + if err != nil { + return "", err + } + + return x + y, nil + } + + return "", nil +} + // GetString will read and return a string value from an ast.BasicLit func GetString(n ast.Node) (string, error) { if node, ok := n.(*ast.BasicLit); ok && node.Kind == token.STRING { return strconv.Unquote(node.Value) } + return "", fmt.Errorf("Unexpected AST node type: %T", n) } @@ -201,22 +236,21 @@ func GetCallStringArgsValues(n ast.Node, _ *Context) []string { return values } -// GetIdentStringValues return the string values of an Ident if they can be resolved -func GetIdentStringValues(ident *ast.Ident) []string { +func getIdentStringValues(ident *ast.Ident, stringFinder func(ast.Node) (string, error)) []string { values := []string{} obj := ident.Obj if obj != nil { switch decl := obj.Decl.(type) { case *ast.ValueSpec: for _, v := range decl.Values { - value, err := GetString(v) + value, err := stringFinder(v) if err == nil { values = append(values, value) } } case *ast.AssignStmt: for _, v := range decl.Rhs { - value, err := GetString(v) + value, err := stringFinder(v) if err == nil { values = append(values, value) } @@ -226,6 +260,18 @@ func GetIdentStringValues(ident *ast.Ident) []string { return values } +// getIdentStringRecursive returns the string of values of an Ident if they can be resolved +// The difference between this and GetIdentStringValues is that it will attempt to resolve the strings recursively, +// if it is passed a *ast.BinaryExpr. See GetStringRecursive for details +func GetIdentStringValuesRecursive(ident *ast.Ident) []string { + return getIdentStringValues(ident, GetStringRecursive) +} + +// GetIdentStringValues return the string values of an Ident if they can be resolved +func GetIdentStringValues(ident *ast.Ident) []string { + return getIdentStringValues(ident, GetString) +} + // GetBinaryExprOperands returns all operands of a binary expression by traversing // the expression tree func GetBinaryExprOperands(be *ast.BinaryExpr) []ast.Node { @@ -301,7 +347,7 @@ func Getenv(key, userDefault string) string { return userDefault } -// GetPkgRelativePath returns the Go relative relative path derived +// GetPkgRelativePath returns the Go relative path derived // form the given path func GetPkgRelativePath(path string) (string, error) { abspath, err := filepath.Abs(path) diff --git a/vendor/github.com/securego/gosec/v2/issue/issue.go b/vendor/github.com/securego/gosec/v2/issue/issue.go index 5bf00dec2..db4d630fa 100644 --- a/vendor/github.com/securego/gosec/v2/issue/issue.go +++ b/vendor/github.com/securego/gosec/v2/issue/issue.go @@ -87,6 +87,7 @@ var ruleToCWE = map[string]string{ "G504": "327", "G505": "327", "G601": "118", + "G602": "118", } // Issue is returned by a gosec rule if it discovers an issue with the scanned code. diff --git a/vendor/github.com/securego/gosec/v2/rule.go b/vendor/github.com/securego/gosec/v2/rule.go index 5e973b6ac..490a25da0 100644 --- a/vendor/github.com/securego/gosec/v2/rule.go +++ b/vendor/github.com/securego/gosec/v2/rule.go @@ -43,7 +43,7 @@ func NewRuleSet() RuleSet { return RuleSet{make(map[reflect.Type][]Rule), make(map[string]bool)} } -// Register adds a trigger for the supplied rule for the the +// Register adds a trigger for the supplied rule for the // specified ast nodes. func (r RuleSet) Register(rule Rule, isSuppressed bool, nodes ...ast.Node) { for _, n := range nodes { diff --git a/vendor/github.com/securego/gosec/v2/rules/hardcoded_credentials.go b/vendor/github.com/securego/gosec/v2/rules/hardcoded_credentials.go index eac50d7c9..ea8386084 100644 --- a/vendor/github.com/securego/gosec/v2/rules/hardcoded_credentials.go +++ b/vendor/github.com/securego/gosec/v2/rules/hardcoded_credentials.go @@ -20,7 +20,7 @@ import ( "regexp" "strconv" - zxcvbn "github.com/nbutton23/zxcvbn-go" + zxcvbn "github.com/ccojocar/zxcvbn-go" "github.com/securego/gosec/v2" "github.com/securego/gosec/v2/issue" @@ -29,6 +29,7 @@ import ( type credentials struct { issue.MetaData pattern *regexp.Regexp + patternValue *regexp.Regexp // Pattern for matching string values (LHS on assign statements) entropyThreshold float64 perCharThreshold float64 truncate int @@ -70,6 +71,7 @@ func (r *credentials) Match(n ast.Node, ctx *gosec.Context) (*issue.Issue, error func (r *credentials) matchAssign(assign *ast.AssignStmt, ctx *gosec.Context) (*issue.Issue, error) { for _, i := range assign.Lhs { if ident, ok := i.(*ast.Ident); ok { + // First check LHS to find anything being assigned to variables whose name appears to be a cred if r.pattern.MatchString(ident.Name) { for _, e := range assign.Rhs { if val, err := gosec.GetString(e); err == nil { @@ -79,12 +81,28 @@ func (r *credentials) matchAssign(assign *ast.AssignStmt, ctx *gosec.Context) (* } } } + + // Now that no names were matched, match the RHS to see if the actual values being assigned are creds + for _, e := range assign.Rhs { + val, err := gosec.GetString(e) + if err != nil { + continue + } + + if r.patternValue.MatchString(val) { + if r.ignoreEntropy || r.isHighEntropyString(val) { + return ctx.NewIssue(assign, r.ID(), r.What, r.Severity, r.Confidence), nil + } + } + } } } return nil, nil } func (r *credentials) matchValueSpec(valueSpec *ast.ValueSpec, ctx *gosec.Context) (*issue.Issue, error) { + // Running match against the variable name(s) first. Will catch any creds whose var name matches the pattern, + // then will go back over to check the values themselves. for index, ident := range valueSpec.Names { if r.pattern.MatchString(ident.Name) && valueSpec.Values != nil { // const foo, bar = "same value" @@ -98,6 +116,18 @@ func (r *credentials) matchValueSpec(valueSpec *ast.ValueSpec, ctx *gosec.Contex } } } + + // Now that no variable names have been matched, match the actual values to find any creds + for _, ident := range valueSpec.Values { + if val, err := gosec.GetString(ident); err == nil { + if r.patternValue.MatchString(val) { + if r.ignoreEntropy || r.isHighEntropyString(val) { + return ctx.NewIssue(valueSpec, r.ID(), r.What, r.Severity, r.Confidence), nil + } + } + } + } + return nil, nil } @@ -119,6 +149,22 @@ func (r *credentials) matchEqualityCheck(binaryExpr *ast.BinaryExpr, ctx *gosec. } } } + + // Now that the variable names have been checked, and no matches were found, make sure that + // either the left or right operands is a string literal so we can match the value. + identStrConst, ok := binaryExpr.X.(*ast.BasicLit) + if !ok { + identStrConst, ok = binaryExpr.Y.(*ast.BasicLit) + } + + if ok && identStrConst.Kind == token.STRING { + s, _ := gosec.GetString(identStrConst) + if r.patternValue.MatchString(s) { + if r.ignoreEntropy || r.isHighEntropyString(s) { + return ctx.NewIssue(binaryExpr, r.ID(), r.What, r.Severity, r.Confidence), nil + } + } + } } return nil, nil } @@ -127,6 +173,7 @@ func (r *credentials) matchEqualityCheck(binaryExpr *ast.BinaryExpr, ctx *gosec. // assigned to variables that appear to be related to credentials. func NewHardcodedCredentials(id string, conf gosec.Config) (gosec.Rule, []ast.Node) { pattern := `(?i)passwd|pass|password|pwd|secret|token|pw|apiKey|bearer|cred` + patternValue := "(?i)(^(.*[:;,](\\s)*)?[a-f0-9]{64}$)|(AIza[0-9A-Za-z-_]{35})|(^(.*[:;,](\\s)*)?github_pat_[a-zA-Z0-9]{22}_[a-zA-Z0-9]{59}$)|(^(.*[:;,](\\s)*)?[0-9a-zA-Z-_]{24}$)" entropyThreshold := 80.0 perCharThreshold := 3.0 ignoreEntropy := false @@ -138,6 +185,13 @@ func NewHardcodedCredentials(id string, conf gosec.Config) (gosec.Rule, []ast.No pattern = cfgPattern } } + + if configPatternValue, ok := conf["patternValue"]; ok { + if cfgPatternValue, ok := configPatternValue.(string); ok { + patternValue = cfgPatternValue + } + } + if configIgnoreEntropy, ok := conf["ignore_entropy"]; ok { if cfgIgnoreEntropy, ok := configIgnoreEntropy.(bool); ok { ignoreEntropy = cfgIgnoreEntropy @@ -168,6 +222,7 @@ func NewHardcodedCredentials(id string, conf gosec.Config) (gosec.Rule, []ast.No return &credentials{ pattern: regexp.MustCompile(pattern), + patternValue: regexp.MustCompile(patternValue), entropyThreshold: entropyThreshold, perCharThreshold: perCharThreshold, ignoreEntropy: ignoreEntropy, diff --git a/vendor/github.com/securego/gosec/v2/rules/implicit_aliasing.go b/vendor/github.com/securego/gosec/v2/rules/implicit_aliasing.go index 70678e29a..32e2fd205 100644 --- a/vendor/github.com/securego/gosec/v2/rules/implicit_aliasing.go +++ b/vendor/github.com/securego/gosec/v2/rules/implicit_aliasing.go @@ -28,6 +28,26 @@ func containsUnary(exprs []*ast.UnaryExpr, expr *ast.UnaryExpr) bool { return false } +func getIdentExpr(expr ast.Expr) *ast.Ident { + switch node := expr.(type) { + case *ast.Ident: + return node + case *ast.SelectorExpr: + return getIdentExpr(node.X) + case *ast.UnaryExpr: + switch e := node.X.(type) { + case *ast.Ident: + return e + case *ast.SelectorExpr: + return getIdentExpr(e.X) + default: + return nil + } + default: + return nil + } +} + func (r *implicitAliasing) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { switch node := n.(type) { case *ast.RangeStmt: @@ -72,8 +92,8 @@ func (r *implicitAliasing) Match(n ast.Node, c *gosec.Context) (*issue.Issue, er } // If we find a unary op of & (reference) of an object within r.aliases, complain. - if ident, ok := node.X.(*ast.Ident); ok && node.Op.String() == "&" { - if _, contains := r.aliases[ident.Obj]; contains { + if identExpr := getIdentExpr(node); identExpr != nil && node.Op.String() == "&" { + if _, contains := r.aliases[identExpr.Obj]; contains { return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil } } diff --git a/vendor/github.com/securego/gosec/v2/rules/rulelist.go b/vendor/github.com/securego/gosec/v2/rules/rulelist.go index d856eccad..316691f61 100644 --- a/vendor/github.com/securego/gosec/v2/rules/rulelist.go +++ b/vendor/github.com/securego/gosec/v2/rules/rulelist.go @@ -107,6 +107,7 @@ func Generate(trackSuppressions bool, filters ...RuleFilter) RuleList { // memory safety {"G601", "Implicit memory aliasing in RangeStmt", NewImplicitAliasing}, + {"G602", "Slice access out of bounds", NewSliceBoundCheck}, } ruleMap := make(map[string]RuleDefinition) diff --git a/vendor/github.com/securego/gosec/v2/rules/slice_bounds.go b/vendor/github.com/securego/gosec/v2/rules/slice_bounds.go new file mode 100644 index 000000000..04811bb50 --- /dev/null +++ b/vendor/github.com/securego/gosec/v2/rules/slice_bounds.go @@ -0,0 +1,405 @@ +package rules + +import ( + "fmt" + "go/ast" + "go/types" + + "github.com/securego/gosec/v2" + "github.com/securego/gosec/v2/issue" +) + +// sliceOutOfBounds is a rule which checks for slices which are accessed outside their capacity, +// either through indexing it out of bounds or through slice expressions whose low or high index +// are out of bounds. +type sliceOutOfBounds struct { + sliceCaps map[*ast.CallExpr]map[string]*int64 // Capacities of slices. Maps function call -> var name -> value. + currentScope *types.Scope // Current scope. Map is cleared when scope changes. + currentFuncName string // Current function. + funcCallArgs map[string][]*int64 // Caps to load once a func declaration is scanned. + issue.MetaData // Metadata for this rule. +} + +// ID returns the rule ID for sliceOutOfBounds: G602. +func (s *sliceOutOfBounds) ID() string { + return s.MetaData.ID +} + +func (s *sliceOutOfBounds) Match(node ast.Node, ctx *gosec.Context) (*issue.Issue, error) { + if s.currentScope == nil { + s.currentScope = ctx.Pkg.Scope() + } else if s.currentScope != ctx.Pkg.Scope() { + s.currentScope = ctx.Pkg.Scope() + + // Clear slice map, since we are in a new scope + sliceMapNil := make(map[string]*int64) + sliceCaps := make(map[*ast.CallExpr]map[string]*int64) + sliceCaps[nil] = sliceMapNil + s.sliceCaps = sliceCaps + } + + switch node := node.(type) { + case *ast.AssignStmt: + return s.matchAssign(node, ctx) + case *ast.SliceExpr: + return s.matchSliceExpr(node, ctx) + case *ast.IndexExpr: + return s.matchIndexExpr(node, ctx) + case *ast.FuncDecl: + s.currentFuncName = node.Name.Name + s.loadArgCaps(node) + case *ast.CallExpr: + if _, ok := node.Fun.(*ast.FuncLit); ok { + // Do nothing with func literals for now. + break + } + + sliceMap := make(map[string]*int64) + s.sliceCaps[node] = sliceMap + s.setupCallArgCaps(node, ctx) + } + return nil, nil +} + +// updateSliceCaps takes in a variable name and a map of calls we are updating the variables for to the updated values +// and will add it to the sliceCaps map. +func (s *sliceOutOfBounds) updateSliceCaps(varName string, caps map[*ast.CallExpr]*int64) { + for callExpr, cap := range caps { + s.sliceCaps[callExpr][varName] = cap + } +} + +// getAllCalls returns all CallExprs that are calls to the given function. +func (s *sliceOutOfBounds) getAllCalls(funcName string, ctx *gosec.Context) []*ast.CallExpr { + calls := []*ast.CallExpr{} + + for callExpr := range s.sliceCaps { + if callExpr != nil { + // Compare the names of the function the code is scanning with the current call we are iterating over + _, callFuncName, err := gosec.GetCallInfo(callExpr, ctx) + if err != nil { + continue + } + + if callFuncName == funcName { + calls = append(calls, callExpr) + } + } + } + return calls +} + +// getSliceCapsForFunc gets all the capacities for slice with given name that are stored for each call to the passed function. +func (s *sliceOutOfBounds) getSliceCapsForFunc(funcName string, varName string, ctx *gosec.Context) map[*ast.CallExpr]*int64 { + caps := make(map[*ast.CallExpr]*int64) + + calls := s.getAllCalls(funcName, ctx) + for _, call := range calls { + if callCaps, ok := s.sliceCaps[call]; ok { + caps[call] = callCaps[varName] + } + } + + return caps +} + +// setupCallArgCaps evaluates and saves the caps for any slices in the args so they can be validated when the function is scanned. +func (s *sliceOutOfBounds) setupCallArgCaps(callExpr *ast.CallExpr, ctx *gosec.Context) { + // Array of caps to be loaded once the function declaration is scanned + funcCallArgs := []*int64{} + + // Get function name + _, funcName, err := gosec.GetCallInfo(callExpr, ctx) + if err != nil { + return + } + + for _, arg := range callExpr.Args { + switch node := arg.(type) { + case *ast.SliceExpr: + caps := s.evaluateSliceExpr(node, ctx) + + // Simplifying assumption: use the lowest capacity. Storing all possible capacities for slices passed + // to a function call would catch the most issues, but would require a data structure like a stack and a + // reworking of the code for scanning itself. Use the lowest capacity, as this would be more likely to + // raise an issue for being out of bounds. + var lowestCap *int64 + for _, cap := range caps { + if cap == nil { + continue + } + + if lowestCap == nil { + lowestCap = cap + } else if *lowestCap > *cap { + lowestCap = cap + } + } + + if lowestCap == nil { + funcCallArgs = append(funcCallArgs, nil) + continue + } + + // Now create a map of just this value to add it to the sliceCaps + funcCallArgs = append(funcCallArgs, lowestCap) + case *ast.Ident: + ident := arg.(*ast.Ident) + caps := s.getSliceCapsForFunc(s.currentFuncName, ident.Name, ctx) + + var lowestCap *int64 + for _, cap := range caps { + if cap == nil { + continue + } + + if lowestCap == nil { + lowestCap = cap + } else if *lowestCap > *cap { + lowestCap = cap + } + } + + if lowestCap == nil { + funcCallArgs = append(funcCallArgs, nil) + continue + } + + // Now create a map of just this value to add it to the sliceCaps + funcCallArgs = append(funcCallArgs, lowestCap) + default: + funcCallArgs = append(funcCallArgs, nil) + } + } + s.funcCallArgs[funcName] = funcCallArgs +} + +// loadArgCaps loads caps that were saved for a call to this function. +func (s *sliceOutOfBounds) loadArgCaps(funcDecl *ast.FuncDecl) { + sliceMap := make(map[string]*int64) + funcName := funcDecl.Name.Name + + // Create a dummmy call expr for the new function. This is so we can still store args for + // functions which are not explicitly called in the code by other functions (specifically, main). + ident := ast.NewIdent(funcName) + dummyCallExpr := ast.CallExpr{ + Fun: ident, + } + + argCaps, ok := s.funcCallArgs[funcName] + if !ok || len(argCaps) == 0 { + s.sliceCaps[&dummyCallExpr] = sliceMap + return + } + + params := funcDecl.Type.Params.List + if len(params) > len(argCaps) { + return // Length of params and args doesn't match, so don't do anything with this. + } + + for it := range params { + capacity := argCaps[it] + if capacity == nil { + continue + } + + if len(params[it].Names) == 0 { + continue + } + + if paramName := params[it].Names[0]; paramName != nil { + sliceMap[paramName.Name] = capacity + } + } + + s.sliceCaps[&dummyCallExpr] = sliceMap +} + +// matchSliceMake matches calls to make() and stores the capacity of the new slice in the map to compare against future slice usage. +func (s *sliceOutOfBounds) matchSliceMake(funcCall *ast.CallExpr, sliceName string, ctx *gosec.Context) (*issue.Issue, error) { + _, funcName, err := gosec.GetCallInfo(funcCall, ctx) + if err != nil || funcName != "make" { + return nil, nil + } + + var capacityArg int + if len(funcCall.Args) < 2 { + return nil, nil // No size passed + } else if len(funcCall.Args) == 2 { + capacityArg = 1 + } else if len(funcCall.Args) == 3 { + capacityArg = 2 + } else { + return nil, nil // Unexpected, args should always be 2 or 3 + } + + // Check and get the capacity of the slice passed to make. It must be a literal value, since we aren't evaluating the expression. + sliceCapLit, ok := funcCall.Args[capacityArg].(*ast.BasicLit) + if !ok { + return nil, nil + } + + capacity, err := gosec.GetInt(sliceCapLit) + if err != nil { + return nil, nil + } + + caps := s.getSliceCapsForFunc(s.currentFuncName, sliceName, ctx) + for callExpr := range caps { + caps[callExpr] = &capacity + } + + s.updateSliceCaps(sliceName, caps) + return nil, nil +} + +// evaluateSliceExpr takes a slice expression and evaluates what the capacity of said slice is for each of the +// calls to the current function. Returns map of the call expressions of each call to the current function to +// the evaluated capacities. +func (s *sliceOutOfBounds) evaluateSliceExpr(node *ast.SliceExpr, ctx *gosec.Context) map[*ast.CallExpr]*int64 { + // Get ident to get name + ident, ok := node.X.(*ast.Ident) + if !ok { + return nil + } + + // Get cap of old slice to calculate this new slice's cap + caps := s.getSliceCapsForFunc(s.currentFuncName, ident.Name, ctx) + for callExpr, oldCap := range caps { + if oldCap == nil { + continue + } + + // Get and check low value + lowIdent, ok := node.Low.(*ast.BasicLit) + if ok && lowIdent != nil { + low, _ := gosec.GetInt(lowIdent) + + newCap := *oldCap - low + caps[callExpr] = &newCap + } else if lowIdent == nil { // If no lower bound, capacity will be same + continue + } + } + + return caps +} + +// matchSliceAssignment matches slice assignments, calculates capacity of slice if possible to store it in map. +func (s *sliceOutOfBounds) matchSliceAssignment(node *ast.SliceExpr, sliceName string, ctx *gosec.Context) (*issue.Issue, error) { + // First do the normal match that verifies the slice expr is not out of bounds + if i, err := s.matchSliceExpr(node, ctx); err != nil { + return i, fmt.Errorf("There was an error while matching a slice expression to check slice bounds for %s: %w", sliceName, err) + } + + // Now that the assignment is (presumably) successfully, we can calculate the capacity and add this new slice to the map + caps := s.evaluateSliceExpr(node, ctx) + s.updateSliceCaps(sliceName, caps) + + return nil, nil +} + +// matchAssign matches checks if an assignment statement is making a slice, or if it is assigning a slice. +func (s *sliceOutOfBounds) matchAssign(node *ast.AssignStmt, ctx *gosec.Context) (*issue.Issue, error) { + // Check RHS for calls to make() so we can get the actual size of the slice + for it, i := range node.Rhs { + // Get the slice name so we can associate the cap with the slice in the map + sliceIdent, ok := node.Lhs[it].(*ast.Ident) + if !ok { + return nil, nil + } + sliceName := sliceIdent.Name + + switch expr := i.(type) { + case *ast.CallExpr: // Check for and handle call to make() + return s.matchSliceMake(expr, sliceName, ctx) + case *ast.SliceExpr: // Handle assignments to a slice + return s.matchSliceAssignment(expr, sliceName, ctx) + } + } + return nil, nil +} + +// matchSliceExpr validates that a given slice expression (eg, slice[10:30]) is not out of bounds. +func (s *sliceOutOfBounds) matchSliceExpr(node *ast.SliceExpr, ctx *gosec.Context) (*issue.Issue, error) { + // First get the slice name so we can check the size in our map + ident, ok := node.X.(*ast.Ident) + if !ok { + return nil, nil + } + + // Get slice cap from the map to compare it against high and low + caps := s.getSliceCapsForFunc(s.currentFuncName, ident.Name, ctx) + + for _, cap := range caps { + if cap == nil { + continue + } + + // Get and check high value + highIdent, ok := node.High.(*ast.BasicLit) + if ok && highIdent != nil { + high, _ := gosec.GetInt(highIdent) + if high > *cap { + return ctx.NewIssue(node, s.ID(), s.What, s.Severity, s.Confidence), nil + } + } + + // Get and check low value + lowIdent, ok := node.Low.(*ast.BasicLit) + if ok && lowIdent != nil { + low, _ := gosec.GetInt(lowIdent) + if low > *cap { + return ctx.NewIssue(node, s.ID(), s.What, s.Severity, s.Confidence), nil + } + } + } + + return nil, nil +} + +// matchIndexExpr validates that an index into a slice is not out of bounds. +func (s *sliceOutOfBounds) matchIndexExpr(node *ast.IndexExpr, ctx *gosec.Context) (*issue.Issue, error) { + // First get the slice name so we can check the size in our map + ident, ok := node.X.(*ast.Ident) + if !ok { + return nil, nil + } + + // Get slice cap from the map to compare it against high and low + caps := s.getSliceCapsForFunc(s.currentFuncName, ident.Name, ctx) + + for _, cap := range caps { + if cap == nil { + continue + } + // Get the index literal + indexIdent, ok := node.Index.(*ast.BasicLit) + if ok && indexIdent != nil { + index, _ := gosec.GetInt(indexIdent) + if index >= *cap { + return ctx.NewIssue(node, s.ID(), s.What, s.Severity, s.Confidence), nil + } + } + } + + return nil, nil +} + +// NewSliceBoundCheck attempts to find any slices being accessed out of bounds +// by reslicing or by being indexed. +func NewSliceBoundCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { + sliceMap := make(map[*ast.CallExpr]map[string]*int64) + + return &sliceOutOfBounds{ + sliceCaps: sliceMap, + currentFuncName: "", + funcCallArgs: make(map[string][]*int64), + MetaData: issue.MetaData{ + ID: id, + Severity: issue.Medium, + Confidence: issue.Medium, + What: "Potentially accessing slice out of bounds", + }, + }, []ast.Node{(*ast.CallExpr)(nil), (*ast.FuncDecl)(nil), (*ast.AssignStmt)(nil), (*ast.SliceExpr)(nil), (*ast.IndexExpr)(nil)} +} diff --git a/vendor/github.com/securego/gosec/v2/rules/sql.go b/vendor/github.com/securego/gosec/v2/rules/sql.go index 4085b5d26..61222bfdb 100644 --- a/vendor/github.com/securego/gosec/v2/rules/sql.go +++ b/vendor/github.com/securego/gosec/v2/rules/sql.go @@ -98,6 +98,32 @@ func (s *sqlStrConcat) ID() string { return s.MetaData.ID } +// findInjectionInBranch walks diwb a set if expressions, and will create new issues if it finds SQL injections +// This method assumes you've already verified that the branch contains SQL syntax +func (s *sqlStrConcat) findInjectionInBranch(ctx *gosec.Context, branch []ast.Expr) *ast.BinaryExpr { + for _, node := range branch { + be, ok := node.(*ast.BinaryExpr) + if !ok { + continue + } + + operands := gosec.GetBinaryExprOperands(be) + + for _, op := range operands { + if _, ok := op.(*ast.BasicLit); ok { + continue + } + + if ident, ok := op.(*ast.Ident); ok && s.checkObject(ident, ctx) { + continue + } + + return be + } + } + return nil +} + // see if we can figure out what it is func (s *sqlStrConcat) checkObject(n *ast.Ident, c *gosec.Context) bool { if n.Obj != nil { @@ -140,6 +166,28 @@ func (s *sqlStrConcat) checkQuery(call *ast.CallExpr, ctx *gosec.Context) (*issu } } + // Handle the case where an injection occurs as an infixed string concatenation, ie "SELECT * FROM foo WHERE name = '" + os.Args[0] + "' AND 1=1" + if id, ok := query.(*ast.Ident); ok { + var match bool + for _, str := range gosec.GetIdentStringValuesRecursive(id) { + if s.MatchPatterns(str) { + match = true + break + } + } + + if !match { + return nil, nil + } + + switch decl := id.Obj.Decl.(type) { + case *ast.AssignStmt: + if injection := s.findInjectionInBranch(ctx, decl.Rhs); injection != nil { + return ctx.NewIssue(injection, s.ID(), s.What, s.Severity, s.Confidence), nil + } + } + } + return nil, nil } @@ -157,6 +205,7 @@ func (s *sqlStrConcat) Match(n ast.Node, ctx *gosec.Context) (*issue.Issue, erro return s.checkQuery(sqlQueryCall, ctx) } } + return nil, nil } @@ -165,7 +214,7 @@ func NewSQLStrConcat(id string, _ gosec.Config) (gosec.Rule, []ast.Node) { rule := &sqlStrConcat{ sqlStatement: sqlStatement{ patterns: []*regexp.Regexp{ - regexp.MustCompile(`(?i)(SELECT|DELETE|INSERT|UPDATE|INTO|FROM|WHERE) `), + regexp.MustCompile("(?i)(SELECT|DELETE|INSERT|UPDATE|INTO|FROM|WHERE)( |\n|\r|\t)"), }, MetaData: issue.MetaData{ ID: id, diff --git a/vendor/github.com/securego/gosec/v2/rules/subproc.go b/vendor/github.com/securego/gosec/v2/rules/subproc.go index ea50d692d..1e2cedaa5 100644 --- a/vendor/github.com/securego/gosec/v2/rules/subproc.go +++ b/vendor/github.com/securego/gosec/v2/rules/subproc.go @@ -97,7 +97,7 @@ func (r *subprocess) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) { } // isContext checks whether or not the node is a CommandContext call or not -// Thi is required in order to skip the first argument from the check. +// This is required in order to skip the first argument from the check. func (r *subprocess) isContext(n ast.Node, ctx *gosec.Context) bool { selector, indent, err := gosec.GetCallInfo(n, ctx) if err != nil { diff --git a/vendor/github.com/tetafro/godot/.golangci.yml b/vendor/github.com/tetafro/godot/.golangci.yml index 2b799b265..920135d40 100644 --- a/vendor/github.com/tetafro/godot/.golangci.yml +++ b/vendor/github.com/tetafro/godot/.golangci.yml @@ -19,7 +19,6 @@ linters: - unused - varcheck - bodyclose - - depguard - dogsled - dupl - funlen @@ -51,7 +50,7 @@ linters: linters-settings: godot: - check-all: true + scope: toplevel issues: exclude-use-default: false diff --git a/vendor/github.com/tetafro/godot/README.md b/vendor/github.com/tetafro/godot/README.md index 3f97b0e39..e8d85fb0a 100644 --- a/vendor/github.com/tetafro/godot/README.md +++ b/vendor/github.com/tetafro/godot/README.md @@ -1,7 +1,7 @@ # godot [](https://raw.githubusercontent.com/tetafro/godot/master/LICENSE) -[](https://github.com/tetafro/godot/actions?query=workflow%3ATest) +[](https://github.com/tetafro/godot/actions) [](https://goreportcard.com/report/github.com/tetafro/godot) [](https://codecov.io/gh/tetafro/godot) diff --git a/vendor/github.com/tetafro/godot/getters.go b/vendor/github.com/tetafro/godot/getters.go index 6153772bd..8adcc46ae 100644 --- a/vendor/github.com/tetafro/godot/getters.go +++ b/vendor/github.com/tetafro/godot/getters.go @@ -5,7 +5,7 @@ import ( "fmt" "go/ast" "go/token" - "io/ioutil" + "os" "regexp" "strings" ) @@ -244,7 +244,7 @@ func getText(comment *ast.CommentGroup, exclude []*regexp.Regexp) (s string) { // readFile reads file and returns it's lines as strings. func readFile(file *ast.File, fset *token.FileSet) ([]string, error) { fname := fset.File(file.Package) - f, err := ioutil.ReadFile(fname.Name()) + f, err := os.ReadFile(fname.Name()) if err != nil { return nil, err } diff --git a/vendor/github.com/tetafro/godot/godot.go b/vendor/github.com/tetafro/godot/godot.go index 3a360a214..19a652fba 100644 --- a/vendor/github.com/tetafro/godot/godot.go +++ b/vendor/github.com/tetafro/godot/godot.go @@ -6,7 +6,6 @@ import ( "fmt" "go/ast" "go/token" - "io/ioutil" "os" "regexp" "sort" @@ -69,7 +68,7 @@ func Run(file *ast.File, fset *token.FileSet, settings Settings) ([]Issue, error // Fix fixes all issues and returns new version of file content. func Fix(path string, file *ast.File, fset *token.FileSet, settings Settings) ([]byte, error) { // Read file - content, err := ioutil.ReadFile(path) // nolint: gosec + content, err := os.ReadFile(path) // nolint: gosec if err != nil { return nil, fmt.Errorf("read file: %v", err) } @@ -115,7 +114,7 @@ func Replace(path string, file *ast.File, fset *token.FileSet, settings Settings return fmt.Errorf("fix issues: %v", err) } - if err := ioutil.WriteFile(path, fixed, mode); err != nil { + if err := os.WriteFile(path, fixed, mode); err != nil { return fmt.Errorf("write file: %v", err) } return nil |
