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 | |
| 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>
71 files changed, 1778 insertions, 413 deletions
@@ -9,7 +9,7 @@ require ( cloud.google.com/go/secretmanager v1.11.1 cloud.google.com/go/storage v1.32.0 github.com/dvyukov/go-fuzz v0.0.0-20220726122315-1d375ef9f9f6 - github.com/golangci/golangci-lint v1.54.1 + github.com/golangci/golangci-lint v1.54.2 github.com/google/go-cmp v0.5.9 github.com/gorilla/handlers v1.5.1 github.com/ianlancetaylor/demangle v0.0.0-20220517205856-0058ec4f073c @@ -38,8 +38,8 @@ require ( cloud.google.com/go/longrunning v0.5.1 // indirect github.com/4meepo/tagalign v1.3.2 // indirect github.com/Abirdcfly/dupword v0.0.12 // indirect - github.com/Antonboom/errname v0.1.10 // indirect - github.com/Antonboom/nilnil v0.1.5 // indirect + github.com/Antonboom/errname v0.1.12 // indirect + github.com/Antonboom/nilnil v0.1.7 // indirect github.com/BurntSushi/toml v1.3.2 // indirect github.com/Djarvur/go-err113 v0.1.0 // indirect github.com/GaijinEntertainment/go-exhaustruct/v3 v3.1.0 // indirect @@ -58,6 +58,7 @@ require ( github.com/breml/errchkjson v0.3.1 // indirect github.com/butuzov/ireturn v0.2.0 // indirect github.com/butuzov/mirror v1.1.0 // indirect + github.com/ccojocar/zxcvbn-go v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/charithe/durationcheck v0.0.10 // indirect github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8 // indirect @@ -140,14 +141,13 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moricho/tparallel v0.3.1 // indirect github.com/nakabonne/nestif v0.3.1 // indirect - github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect github.com/nishanths/exhaustive v0.11.0 // indirect github.com/nishanths/predeclared v0.2.2 // indirect - github.com/nunnatsa/ginkgolinter v0.13.3 // indirect + github.com/nunnatsa/ginkgolinter v0.13.5 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/polyfloyd/go-errorlint v1.4.3 // indirect + github.com/polyfloyd/go-errorlint v1.4.4 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.10.1 // indirect @@ -160,8 +160,8 @@ require ( github.com/ryanrolds/sqlclosecheck v0.4.0 // indirect github.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect github.com/sashamelentyev/interfacebloat v1.1.0 // indirect - github.com/sashamelentyev/usestdlibvars v1.23.0 // indirect - github.com/securego/gosec/v2 v2.16.0 // indirect + github.com/sashamelentyev/usestdlibvars v1.24.0 // indirect + github.com/securego/gosec/v2 v2.17.0 // indirect github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/sivchari/containedctx v1.0.3 // indirect @@ -181,7 +181,7 @@ require ( github.com/subosito/gotenv v1.4.2 // indirect github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c // indirect github.com/tdakkota/asciicheck v0.2.0 // indirect - github.com/tetafro/godot v1.4.11 // indirect + github.com/tetafro/godot v1.4.14 // indirect github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 // indirect github.com/timonwong/loggercheck v0.9.4 // indirect github.com/tomarrell/wrapcheck/v2 v2.8.1 // indirect @@ -195,7 +195,7 @@ require ( github.com/ykadowak/zerologlint v0.1.3 // indirect gitlab.com/bosi/decorder v0.4.0 // indirect go.opencensus.io v0.24.0 // indirect - go.tmz.dev/musttag v0.7.1 // indirect + go.tmz.dev/musttag v0.7.2 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.9.0 // indirect go.uber.org/zap v1.24.0 // indirect @@ -212,7 +212,7 @@ require ( google.golang.org/protobuf v1.31.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - honnef.co/go/tools v0.4.3 // indirect + honnef.co/go/tools v0.4.5 // indirect mvdan.cc/gofumpt v0.5.0 // indirect mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect @@ -67,10 +67,10 @@ github.com/4meepo/tagalign v1.3.2 h1:1idD3yxlRGV18VjqtDbqYvQ5pXqQS0wO2dn6M3XstvI github.com/4meepo/tagalign v1.3.2/go.mod h1:Q9c1rYMZJc9dPRkbQPpcBNCLEmY2njbAsXhQOZFE2dE= github.com/Abirdcfly/dupword v0.0.12 h1:56NnOyrXzChj07BDFjeRA+IUzSz01jmzEq+G4kEgFhc= github.com/Abirdcfly/dupword v0.0.12/go.mod h1:+us/TGct/nI9Ndcbcp3rgNcQzctTj68pq7TcgNpLfdI= -github.com/Antonboom/errname v0.1.10 h1:RZ7cYo/GuZqjr1nuJLNe8ZH+a+Jd9DaZzttWzak9Bls= -github.com/Antonboom/errname v0.1.10/go.mod h1:xLeiCIrvVNpUtsN0wxAh05bNIZpqE22/qDMnTBTttiA= -github.com/Antonboom/nilnil v0.1.5 h1:X2JAdEVcbPaOom2TUa1FxZ3uyuUlex0XMLGYMemu6l0= -github.com/Antonboom/nilnil v0.1.5/go.mod h1:I24toVuBKhfP5teihGWctrRiPbRKHwZIFOvc6v3HZXk= +github.com/Antonboom/errname v0.1.12 h1:oh9ak2zUtsLp5oaEd/erjB4GPu9w19NyoIskZClDcQY= +github.com/Antonboom/errname v0.1.12/go.mod h1:bK7todrzvlaZoQagP1orKzWXv59X/x0W0Io2XT1Ssro= +github.com/Antonboom/nilnil v0.1.7 h1:ofgL+BA7vlA1K2wNQOsHzLJ2Pw5B5DpWRLdDAVvvTow= +github.com/Antonboom/nilnil v0.1.7/go.mod h1:TP+ScQWVEq0eSIxqU8CbdT5DFWoHp0MbP+KMUO1BKYQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= @@ -125,6 +125,8 @@ github.com/butuzov/ireturn v0.2.0 h1:kCHi+YzC150GE98WFuZQu9yrTn6GEydO2AuPLbTgnO4 github.com/butuzov/ireturn v0.2.0/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc= github.com/butuzov/mirror v1.1.0 h1:ZqX54gBVMXu78QLoiqdwpl2mgmoOJTk7s4p4o+0avZI= github.com/butuzov/mirror v1.1.0/go.mod h1:8Q0BdQU6rC6WILDiBM60DBfvV78OLJmMmixe7GF45AE= +github.com/ccojocar/zxcvbn-go v1.0.1 h1:+sxrANSCj6CdadkcMnvde/GWU1vZiiXRbqYSCalV4/4= +github.com/ccojocar/zxcvbn-go v1.0.1/go.mod h1:g1qkXtUSvHP8lhHp5GrSmTz6uWALGRMQdw6Qnz/hi60= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -273,8 +275,8 @@ github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe h1:6RGUuS7EGotKx6 github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe/go.mod h1:gjqyPShc/m8pEMpk0a3SeagVb0kaqvhscv+i9jI5ZhQ= github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 h1:amWTbTGqOZ71ruzrdA+Nx5WA3tV1N0goTspwmKCQvBY= github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2/go.mod h1:9wOXstvyDRshQ9LggQuzBCGysxs3b6Uo/1MvYCR2NMs= -github.com/golangci/golangci-lint v1.54.1 h1:0qMrH1gkeIBqCZaaAm5Fwq4xys9rO/lJofHfZURIFFk= -github.com/golangci/golangci-lint v1.54.1/go.mod h1:JK47+qksV/t2mAz9YvndwT0ZLW4A1rvDljOs3g9jblo= +github.com/golangci/golangci-lint v1.54.2 h1:oR9zxfWYxt7hFqk6+fw6Enr+E7F0SN2nqHhJYyIb0yo= +github.com/golangci/golangci-lint v1.54.2/go.mod h1:vnsaCTPKCI2wreL9tv7RkHDwUrz3htLjed6+6UsvcwU= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= @@ -467,18 +469,16 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81U= github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE= -github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6FxaNu/BnU2OAaLF86eTVhP2hjTB6iMvItA= -github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= github.com/nishanths/exhaustive v0.11.0 h1:T3I8nUGhl/Cwu5Z2hfc92l0e04D2GEW6e0l8pzda2l0= github.com/nishanths/exhaustive v0.11.0/go.mod h1:RqwDsZ1xY0dNdqHho2z6X+bgzizwbLYOWnZbbl2wLB4= github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk= github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= -github.com/nunnatsa/ginkgolinter v0.13.3 h1:wEvjrzSMfDdnoWkctignX9QTf4rT9f4GkQ3uVoXBmiU= -github.com/nunnatsa/ginkgolinter v0.13.3/go.mod h1:aTKXo8WddENYxNEFT+4ZxEgWXqlD9uMD3w9Bfw/ABEc= +github.com/nunnatsa/ginkgolinter v0.13.5 h1:fOsPB4CEZOPkyMqF4B9hoqOpooFWU7vWSVkCSscVpgU= +github.com/nunnatsa/ginkgolinter v0.13.5/go.mod h1:OBHy4536xtuX3102NM63XRtOyxqZOO02chsaeDWXVO8= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= -github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/otiai10/copy v1.2.0 h1:HvG945u96iNadPoG2/Ja2+AUJeW5YuFQMixq9yirC+k= github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= @@ -497,8 +497,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polyfloyd/go-errorlint v1.4.3 h1:P6NALOLV8BrWhm6PsqOraUK05E5h8IZnpXYJ+CIg+0U= -github.com/polyfloyd/go-errorlint v1.4.3/go.mod h1:VPlWPh6hB/wruVG803SuNpLuTGNjLHYlvcdSy4RhdPA= +github.com/polyfloyd/go-errorlint v1.4.4 h1:A9gytp+p6TYqeALTYRoxJESYP8wJRETRX2xzGWFsEBU= +github.com/polyfloyd/go-errorlint v1.4.4/go.mod h1:ry5NqF7l9Q77V+XqAfUg1zfryrEtyac3G5+WVpIK0xU= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= @@ -550,10 +550,10 @@ github.com/sanposhiho/wastedassign/v2 v2.0.7 h1:J+6nrY4VW+gC9xFzUc+XjPD3g3wF3je/ github.com/sanposhiho/wastedassign/v2 v2.0.7/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tMEOsumirXcOJqAw= github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ= -github.com/sashamelentyev/usestdlibvars v1.23.0 h1:01h+/2Kd+NblNItNeux0veSL5cBF1jbEOPrEhDzGYq0= -github.com/sashamelentyev/usestdlibvars v1.23.0/go.mod h1:YPwr/Y1LATzHI93CqoPUN/2BzGQ/6N/cl/KwgR0B/aU= -github.com/securego/gosec/v2 v2.16.0 h1:Pi0JKoasQQ3NnoRao/ww/N/XdynIB9NRYYZT5CyOs5U= -github.com/securego/gosec/v2 v2.16.0/go.mod h1:xvLcVZqUfo4aAQu56TNv7/Ltz6emAOQAEsrZrt7uGlI= +github.com/sashamelentyev/usestdlibvars v1.24.0 h1:MKNzmXtGh5N0y74Z/CIaJh4GlB364l0K1RUT08WSWAc= +github.com/sashamelentyev/usestdlibvars v1.24.0/go.mod h1:9cYkq+gYJ+a5W2RPdhfaSCnTVUC1OQP/bSiiBhq3OZE= +github.com/securego/gosec/v2 v2.17.0 h1:ZpAStTDKY39insEG9OH6kV3IkhQZPTq9a9eGOLOjcdI= +github.com/securego/gosec/v2 v2.17.0/go.mod h1:lt+mgC91VSmriVoJLentrMkRCYs+HLTBnUFUBuhV2hc= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= @@ -594,7 +594,6 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -616,8 +615,8 @@ github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0= github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag= github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= -github.com/tetafro/godot v1.4.11 h1:BVoBIqAf/2QdbFmSwAWnaIqDivZdOV0ZRwEm6jivLKw= -github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8= +github.com/tetafro/godot v1.4.14 h1:ScO641OHpf9UpHPk8fCknSuXNMpi4iFlwuWoBs3L+1s= +github.com/tetafro/godot v1.4.14/go.mod h1:2oVxTBSftRTh4+MVfUaUXR6bn2GDXCaMcOG4Dk3rfio= github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 h1:quvGphlmUVU+nhpFa4gg4yJyTRJ13reZMDHrKwYw53M= github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966/go.mod h1:27bSVNWSBOHm+qRp1T9qzaIpsWEP6TbUnei/43HK+PQ= github.com/timonwong/loggercheck v0.9.4 h1:HKKhqrjcVj8sxL7K77beXh0adEm6DLjV/QOGeMXEVi4= @@ -651,7 +650,7 @@ github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= gitlab.com/bosi/decorder v0.4.0 h1:HWuxAhSxIvsITcXeP+iIRg9d1cVfvVkmlF7M68GaoDY= gitlab.com/bosi/decorder v0.4.0/go.mod h1:xarnteyUoJiOTEldDysquWKTVDCKo2TOIOIibSuWqOg= -go-simpler.org/assert v0.5.0 h1:+5L/lajuQtzmbtEfh69sr5cRf2/xZzyJhFjoOz/PPqs= +go-simpler.org/assert v0.6.0 h1:QxSrXa4oRuo/1eHMXSBFHKvJIpWABayzKldqZyugG7E= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -661,8 +660,8 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.tmz.dev/musttag v0.7.1 h1:9lFmeSFnFfPuMq4IksHGomItE6NgKMNW2Nt2FPOhCfU= -go.tmz.dev/musttag v0.7.1/go.mod h1:oJLkpR56EsIryktZJk/B0IroSMi37YWver47fibGh5U= +go.tmz.dev/musttag v0.7.2 h1:1J6S9ipDbalBSODNT5jCep8dhZyMr4ttnjQagmGYR5s= +go.tmz.dev/musttag v0.7.2/go.mod h1:m6q5NiiSKMnQYokefa2xGoyoXnrswCbJ0AWYzf4Zs28= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= @@ -1128,8 +1127,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.4.3 h1:o/n5/K5gXqk8Gozvs2cnL0F2S1/g1vcGCAx2vETjITw= -honnef.co/go/tools v0.4.3/go.mod h1:36ZgoUOrqOk1GxwHhyryEkq8FQWkUO2xGuSMhUCcdvA= +honnef.co/go/tools v0.4.5 h1:YGD4H+SuIOOqsyoLOpZDWcieM28W47/zRO7f+9V3nvo= +honnef.co/go/tools v0.4.5/go.mod h1:GUV+uIBCLpdf0/v6UhHHG/yzI/z6qPskBeQCjcNB96k= mvdan.cc/gofumpt v0.5.0 h1:0EQ+Z56k8tXjj/6TQD25BFNKQXpCvT0rnansIc7Ug5E= mvdan.cc/gofumpt v0.5.0/go.mod h1:HBeVDtMKRZpXyxFciAirzdKklDlGu8aAy1wEbH5Y9js= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= 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 diff --git a/vendor/go.tmz.dev/musttag/utils.go b/vendor/go.tmz.dev/musttag/utils.go index 09b51a145..673747f15 100644 --- a/vendor/go.tmz.dev/musttag/utils.go +++ b/vendor/go.tmz.dev/musttag/utils.go @@ -2,29 +2,56 @@ package musttag import ( "encoding/json" + "errors" "fmt" + "io" + "os" "os/exec" "strings" ) +var ( + getwd = os.Getwd + + commandOutput = func(name string, args ...string) (string, error) { + output, err := exec.Command(name, args...).Output() + return string(output), err + } +) + func getMainModule() (string, error) { args := []string{"go", "list", "-m", "-json"} - data, err := exec.Command(args[0], args[1:]...).Output() + output, err := commandOutput(args[0], args[1:]...) if err != nil { return "", fmt.Errorf("running `%s`: %w", strings.Join(args, " "), err) } - var module struct { - Path string `json:"Path"` - Main bool `json:"Main"` - Dir string `json:"Dir"` - GoMod string `json:"GoMod"` - GoVersion string `json:"GoVersion"` - } - if err := json.Unmarshal(data, &module); err != nil { - return "", fmt.Errorf("decoding json: %w: %s", err, string(data)) + cwd, err := getwd() + if err != nil { + return "", fmt.Errorf("getting wd: %w", err) } - return module.Path, nil + decoder := json.NewDecoder(strings.NewReader(output)) + + for { + // multiple JSON objects will be returned when using Go workspaces; see #63 for details. + var module struct { + Path string `json:"Path"` + Main bool `json:"Main"` + Dir string `json:"Dir"` + GoMod string `json:"GoMod"` + GoVersion string `json:"GoVersion"` + } + if err := decoder.Decode(&module); err != nil { + if errors.Is(err, io.EOF) { + return "", fmt.Errorf("main module not found\n%s", output) + } + return "", fmt.Errorf("decoding json: %w\n%s", err, output) + } + + if module.Main && strings.HasPrefix(cwd, module.Dir) { + return module.Path, nil + } + } } diff --git a/vendor/golang.org/x/tools/go/analysis/passes/directive/directive.go b/vendor/golang.org/x/tools/go/analysis/passes/directive/directive.go new file mode 100644 index 000000000..1146d7be4 --- /dev/null +++ b/vendor/golang.org/x/tools/go/analysis/passes/directive/directive.go @@ -0,0 +1,217 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package directive defines an Analyzer that checks known Go toolchain directives. +package directive + +import ( + "go/ast" + "go/parser" + "go/token" + "strings" + "unicode" + "unicode/utf8" + + "golang.org/x/tools/go/analysis" + "golang.org/x/tools/go/analysis/passes/internal/analysisutil" +) + +const Doc = `check Go toolchain directives such as //go:debug + +This analyzer checks for problems with known Go toolchain directives +in all Go source files in a package directory, even those excluded by +//go:build constraints, and all non-Go source files too. + +For //go:debug (see https://go.dev/doc/godebug), the analyzer checks +that the directives are placed only in Go source files, only above the +package comment, and only in package main or *_test.go files. + +Support for other known directives may be added in the future. + +This analyzer does not check //go:build, which is handled by the +buildtag analyzer. +` + +var Analyzer = &analysis.Analyzer{ + Name: "directive", + Doc: Doc, + URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/directive", + Run: runDirective, +} + +func runDirective(pass *analysis.Pass) (interface{}, error) { + for _, f := range pass.Files { + checkGoFile(pass, f) + } + for _, name := range pass.OtherFiles { + if err := checkOtherFile(pass, name); err != nil { + return nil, err + } + } + for _, name := range pass.IgnoredFiles { + if strings.HasSuffix(name, ".go") { + f, err := parser.ParseFile(pass.Fset, name, nil, parser.ParseComments) + if err != nil { + // Not valid Go source code - not our job to diagnose, so ignore. + continue + } + checkGoFile(pass, f) + } else { + if err := checkOtherFile(pass, name); err != nil { + return nil, err + } + } + } + return nil, nil +} + +func checkGoFile(pass *analysis.Pass, f *ast.File) { + check := newChecker(pass, pass.Fset.File(f.Package).Name(), f) + + for _, group := range f.Comments { + // A +build comment is ignored after or adjoining the package declaration. + if group.End()+1 >= f.Package { + check.inHeader = false + } + // A //go:build comment is ignored after the package declaration + // (but adjoining it is OK, in contrast to +build comments). + if group.Pos() >= f.Package { + check.inHeader = false + } + + // Check each line of a //-comment. + for _, c := range group.List { + check.comment(c.Slash, c.Text) + } + } +} + +func checkOtherFile(pass *analysis.Pass, filename string) error { + // We cannot use the Go parser, since is not a Go source file. + // Read the raw bytes instead. + content, tf, err := analysisutil.ReadFile(pass.Fset, filename) + if err != nil { + return err + } + + check := newChecker(pass, filename, nil) + check.nonGoFile(token.Pos(tf.Base()), string(content)) + return nil +} + +type checker struct { + pass *analysis.Pass + filename string + file *ast.File // nil for non-Go file + inHeader bool // in file header (before package declaration) + inStar bool // currently in a /* */ comment +} + +func newChecker(pass *analysis.Pass, filename string, file *ast.File) *checker { + return &checker{ + pass: pass, + filename: filename, + file: file, + inHeader: true, + } +} + +func (check *checker) nonGoFile(pos token.Pos, fullText string) { + // Process each line. + text := fullText + inStar := false + for text != "" { + offset := len(fullText) - len(text) + var line string + line, text, _ = stringsCut(text, "\n") + + if !inStar && strings.HasPrefix(line, "//") { + check.comment(pos+token.Pos(offset), line) + continue + } + + // Skip over, cut out any /* */ comments, + // to avoid being confused by a commented-out // comment. + for { + line = strings.TrimSpace(line) + if inStar { + var ok bool + _, line, ok = stringsCut(line, "*/") + if !ok { + break + } + inStar = false + continue + } + line, inStar = stringsCutPrefix(line, "/*") + if !inStar { + break + } + } + if line != "" { + // Found non-comment non-blank line. + // Ends space for valid //go:build comments, + // but also ends the fraction of the file we can + // reliably parse. From this point on we might + // incorrectly flag "comments" inside multiline + // string constants or anything else (this might + // not even be a Go program). So stop. + break + } + } +} + +func (check *checker) comment(pos token.Pos, line string) { + if !strings.HasPrefix(line, "//go:") { + return + } + // testing hack: stop at // ERROR + if i := strings.Index(line, " // ERROR "); i >= 0 { + line = line[:i] + } + + verb := line + if i := strings.IndexFunc(verb, unicode.IsSpace); i >= 0 { + verb = verb[:i] + if line[i] != ' ' && line[i] != '\t' && line[i] != '\n' { + r, _ := utf8.DecodeRuneInString(line[i:]) + check.pass.Reportf(pos, "invalid space %#q in %s directive", r, verb) + } + } + + switch verb { + default: + // TODO: Use the go language version for the file. + // If that version is not newer than us, then we can + // report unknown directives. + + case "//go:build": + // Ignore. The buildtag analyzer reports misplaced comments. + + case "//go:debug": + if check.file == nil { + check.pass.Reportf(pos, "//go:debug directive only valid in Go source files") + } else if check.file.Name.Name != "main" && !strings.HasSuffix(check.filename, "_test.go") { + check.pass.Reportf(pos, "//go:debug directive only valid in package main or test") + } else if !check.inHeader { + check.pass.Reportf(pos, "//go:debug directive only valid before package declaration") + } + } +} + +// Go 1.18 strings.Cut. +func stringsCut(s, sep string) (before, after string, found bool) { + if i := strings.Index(s, sep); i >= 0 { + return s[:i], s[i+len(sep):], true + } + return s, "", false +} + +// Go 1.20 strings.CutPrefix. +func stringsCutPrefix(s, prefix string) (after string, found bool) { + if !strings.HasPrefix(s, prefix) { + return s, false + } + return s[len(prefix):], true +} diff --git a/vendor/golang.org/x/tools/go/analysis/passes/slog/doc.go b/vendor/golang.org/x/tools/go/analysis/passes/slog/doc.go new file mode 100644 index 000000000..ecb10e094 --- /dev/null +++ b/vendor/golang.org/x/tools/go/analysis/passes/slog/doc.go @@ -0,0 +1,23 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package slog defines an Analyzer that checks for +// mismatched key-value pairs in log/slog calls. +// +// # Analyzer slog +// +// slog: check for invalid structured logging calls +// +// The slog checker looks for calls to functions from the log/slog +// package that take alternating key-value pairs. It reports calls +// where an argument in a key position is neither a string nor a +// slog.Attr, and where a final key is missing its value. +// For example,it would report +// +// slog.Warn("message", 11, "k") // slog.Warn arg "11" should be a string or a slog.Attr +// +// and +// +// slog.Info("message", "k1", v1, "k2") // call to slog.Info missing a final value +package slog diff --git a/vendor/golang.org/x/tools/go/analysis/passes/slog/slog.go b/vendor/golang.org/x/tools/go/analysis/passes/slog/slog.go new file mode 100644 index 000000000..92c1da8ef --- /dev/null +++ b/vendor/golang.org/x/tools/go/analysis/passes/slog/slog.go @@ -0,0 +1,243 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// TODO(jba) deduce which functions wrap the log/slog functions, and use the +// fact mechanism to propagate this information, so we can provide diagnostics +// for user-supplied wrappers. + +package slog + +import ( + _ "embed" + "fmt" + "go/ast" + "go/token" + "go/types" + + "golang.org/x/tools/go/analysis" + "golang.org/x/tools/go/analysis/passes/inspect" + "golang.org/x/tools/go/analysis/passes/internal/analysisutil" + "golang.org/x/tools/go/ast/inspector" + "golang.org/x/tools/go/types/typeutil" +) + +//go:embed doc.go +var doc string + +var Analyzer = &analysis.Analyzer{ + Name: "slog", + Doc: analysisutil.MustExtractDoc(doc, "slog"), + URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/slog", + Requires: []*analysis.Analyzer{inspect.Analyzer}, + Run: run, +} + +var stringType = types.Universe.Lookup("string").Type() + +// A position describes what is expected to appear in an argument position. +type position int + +const ( + // key is an argument position that should hold a string key or an Attr. + key position = iota + // value is an argument position that should hold a value. + value + // unknown represents that we do not know if position should hold a key or a value. + unknown +) + +func run(pass *analysis.Pass) (any, error) { + inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) + nodeFilter := []ast.Node{ + (*ast.CallExpr)(nil), + } + inspect.Preorder(nodeFilter, func(node ast.Node) { + call := node.(*ast.CallExpr) + fn := typeutil.StaticCallee(pass.TypesInfo, call) + if fn == nil { + return // not a static call + } + if call.Ellipsis != token.NoPos { + return // skip calls with "..." args + } + skipArgs, ok := kvFuncSkipArgs(fn) + if !ok { + // Not a slog function that takes key-value pairs. + return + } + if isMethodExpr(pass.TypesInfo, call) { + // Call is to a method value. Skip the first argument. + skipArgs++ + } + if len(call.Args) <= skipArgs { + // Too few args; perhaps there are no k-v pairs. + return + } + + // Check this call. + // The first position should hold a key or Attr. + pos := key + var unknownArg ast.Expr // nil or the last unknown argument + for _, arg := range call.Args[skipArgs:] { + t := pass.TypesInfo.Types[arg].Type + switch pos { + case key: + // Expect a string or Attr. + switch { + case t == stringType: + pos = value + case isAttr(t): + pos = key + case types.IsInterface(t): + // As we do not do dataflow, we do not know what the dynamic type is. + // It could be a string or an Attr so we don't know what to expect next. + pos = unknown + default: + if unknownArg == nil { + pass.ReportRangef(arg, "%s arg %q should be a string or a slog.Attr (possible missing key or value)", + shortName(fn), analysisutil.Format(pass.Fset, arg)) + } else { + pass.ReportRangef(arg, "%s arg %q should probably be a string or a slog.Attr (previous arg %q cannot be a key)", + shortName(fn), analysisutil.Format(pass.Fset, arg), analysisutil.Format(pass.Fset, unknownArg)) + } + // Stop here so we report at most one missing key per call. + return + } + + case value: + // Anything can appear in this position. + // The next position should be a key. + pos = key + + case unknown: + // Once we encounter an unknown position, we can never be + // sure if a problem later or at the end of the call is due to a + // missing final value, or a non-key in key position. + // In both cases, unknownArg != nil. + unknownArg = arg + + // We don't know what is expected about this position, but all hope is not lost. + if t != stringType && !isAttr(t) && !types.IsInterface(t) { + // This argument is definitely not a key. + // + // unknownArg cannot have been a key, in which case this is the + // corresponding value, and the next position should hold another key. + pos = key + } + } + } + if pos == value { + if unknownArg == nil { + pass.ReportRangef(call, "call to %s missing a final value", shortName(fn)) + } else { + pass.ReportRangef(call, "call to %s has a missing or misplaced value", shortName(fn)) + } + } + }) + return nil, nil +} + +func isAttr(t types.Type) bool { + return isNamed(t, "log/slog", "Attr") +} + +// shortName returns a name for the function that is shorter than FullName. +// Examples: +// +// "slog.Info" (instead of "log/slog.Info") +// "slog.Logger.With" (instead of "(*log/slog.Logger).With") +func shortName(fn *types.Func) string { + var r string + if recv := fn.Type().(*types.Signature).Recv(); recv != nil { + t := recv.Type() + if pt, ok := t.(*types.Pointer); ok { + t = pt.Elem() + } + if nt, ok := t.(*types.Named); ok { + r = nt.Obj().Name() + } else { + r = recv.Type().String() + } + r += "." + } + return fmt.Sprintf("%s.%s%s", fn.Pkg().Name(), r, fn.Name()) +} + +// If fn is a slog function that has a ...any parameter for key-value pairs, +// kvFuncSkipArgs returns the number of arguments to skip over to reach the +// corresponding arguments, and true. +// Otherwise it returns (0, false). +func kvFuncSkipArgs(fn *types.Func) (int, bool) { + if pkg := fn.Pkg(); pkg == nil || pkg.Path() != "log/slog" { + return 0, false + } + var recvName string // by default a slog package function + recv := fn.Type().(*types.Signature).Recv() + if recv != nil { + t := recv.Type() + if pt, ok := t.(*types.Pointer); ok { + t = pt.Elem() + } + if nt, ok := t.(*types.Named); !ok { + return 0, false + } else { + recvName = nt.Obj().Name() + } + } + skip, ok := kvFuncs[recvName][fn.Name()] + return skip, ok +} + +// The names of functions and methods in log/slog that take +// ...any for key-value pairs, mapped to the number of initial args to skip in +// order to get to the ones that match the ...any parameter. +// The first key is the dereferenced receiver type name, or "" for a function. +var kvFuncs = map[string]map[string]int{ + "": map[string]int{ + "Debug": 1, + "Info": 1, + "Warn": 1, + "Error": 1, + "DebugContext": 2, + "InfoContext": 2, + "WarnContext": 2, + "ErrorContext": 2, + "Log": 3, + "Group": 1, + }, + "Logger": map[string]int{ + "Debug": 1, + "Info": 1, + "Warn": 1, + "Error": 1, + "DebugContext": 2, + "InfoContext": 2, + "WarnContext": 2, + "ErrorContext": 2, + "Log": 3, + "With": 0, + }, + "Record": map[string]int{ + "Add": 0, + }, +} + +// isMethodExpr reports whether a call is to a MethodExpr. +func isMethodExpr(info *types.Info, c *ast.CallExpr) bool { + s, ok := c.Fun.(*ast.SelectorExpr) + if !ok { + return false + } + sel := info.Selections[s] + return sel != nil && sel.Kind() == types.MethodExpr +} + +// isNamed reports whether t is exactly a named type in a package with a given path. +func isNamed(t types.Type, path, name string) bool { + if n, ok := t.(*types.Named); ok { + obj := n.Obj() + return obj.Pkg() != nil && obj.Pkg().Path() == path && obj.Name() == name + } + return false +} diff --git a/vendor/honnef.co/go/tools/analysis/lint/lint.go b/vendor/honnef.co/go/tools/analysis/lint/lint.go index b4e37d6f4..7d116a23d 100644 --- a/vendor/honnef.co/go/tools/analysis/lint/lint.go +++ b/vendor/honnef.co/go/tools/analysis/lint/lint.go @@ -8,6 +8,7 @@ import ( "go/ast" "go/build" "go/token" + "regexp" "strconv" "strings" @@ -206,21 +207,28 @@ func (v *VersionFlag) String() string { return fmt.Sprintf("1.%d", *v) } -func (v *VersionFlag) Set(s string) error { - if len(s) < 3 { - return fmt.Errorf("invalid Go version: %q", s) - } - if s[0] != '1' { - return fmt.Errorf("invalid Go version: %q", s) - } - if s[1] != '.' { - return fmt.Errorf("invalid Go version: %q", s) +var goVersionRE = regexp.MustCompile(`^(?:go)?1.(\d+).*$`) + +// ParseGoVersion parses Go versions of the form 1.M, 1.M.N, or 1.M.NrcR, with an optional "go" prefix. It assumes that +// versions have already been verified and are valid. +func ParseGoVersion(s string) (int, bool) { + m := goVersionRE.FindStringSubmatch(s) + if m == nil { + return 0, false } - i, err := strconv.Atoi(s[2:]) + n, err := strconv.Atoi(m[1]) if err != nil { + return 0, false + } + return n, true +} + +func (v *VersionFlag) Set(s string) error { + n, ok := ParseGoVersion(s) + if !ok { return fmt.Errorf("invalid Go version: %q", s) } - *v = VersionFlag(i) + *v = VersionFlag(n) return nil } diff --git a/vendor/honnef.co/go/tools/go/ir/builder.go b/vendor/honnef.co/go/tools/go/ir/builder.go index d56975b72..1a77ed042 100644 --- a/vendor/honnef.co/go/tools/go/ir/builder.go +++ b/vendor/honnef.co/go/tools/go/ir/builder.go @@ -1145,16 +1145,13 @@ func (b *builder) arrayLen(fn *Function, elts []ast.Expr) int64 { // x = T{a: x.a} // // all the reads must occur before all the writes. This is implicitly handled by the write buffering effected by -// compositeElement. +// compositeElement and explicitly by the storebuf for when we don't use CompositeValue. // // A CompositeLit may have pointer type only in the recursive (nested) // case when the type name is implicit. e.g. in []*T{{}}, the inner // literal has type *T behaves like &T{}. // In that case, addr must hold a T, not a *T. func (b *builder) compLit(fn *Function, addr Value, e *ast.CompositeLit, isZero bool, sb *storebuf) { - // Even though we no longer need storebuf for nested composite literals (because compositeElements act as buffers - // themselves), we still need storebuf for things like multiple assignment, e.g. 't.F1, t.F2 = T2{1}, T2{t.F1.X}' - typ := deref(fn.Pkg.typeOf(e)) switch t := typeutil.CoreType(typ).(type) { case *types.Struct: @@ -1220,41 +1217,77 @@ func (b *builder) compLit(fn *Function, addr Value, e *ast.CompositeLit, isZero final = zc } } else { - v := &CompositeValue{ - Values: make([]Value, at.Len()), - } - zc := emitConst(fn, zeroConst(at.Elem())) - for i := range v.Values { - v.Values[i] = zc - } - v.setType(at) + if at.Len() == int64(len(e.Elts)) { + // The literal specifies all elements, so we can use a composite value + v := &CompositeValue{ + Values: make([]Value, at.Len()), + } + zc := emitConst(fn, zeroConst(at.Elem())) + for i := range v.Values { + v.Values[i] = zc + } + v.setType(at) - var idx *Const - for _, e := range e.Elts { - if kv, ok := e.(*ast.KeyValueExpr); ok { - idx = b.expr(fn, kv.Key).(*Const) - e = kv.Value - } else { - var idxval int64 - if idx != nil { - idxval = idx.Int64() + 1 + var idx *Const + for _, e := range e.Elts { + if kv, ok := e.(*ast.KeyValueExpr); ok { + idx = b.expr(fn, kv.Key).(*Const) + e = kv.Value + } else { + var idxval int64 + if idx != nil { + idxval = idx.Int64() + 1 + } + idx = emitConst(fn, intConst(idxval)).(*Const) } - idx = emitConst(fn, intConst(idxval)).(*Const) - } - iaddr := &compositeElement{ - cv: v, - idx: int(idx.Int64()), - t: at.Elem(), - expr: e, + iaddr := &compositeElement{ + cv: v, + idx: int(idx.Int64()), + t: at.Elem(), + expr: e, + } + + b.assign(fn, iaddr, e, true, sb, e) + v.Bitmap.SetBit(&v.Bitmap, int(idx.Int64()), 1) + v.NumSet++ + } + final = v + fn.emit(v, e) + } else { + // Not all elements are specified. Populate the array with a series of stores, to guard against literals + // like []int{1<<62: 1}. + if !isZero { + // memclear + sb.store(&address{array, nil}, zeroValue(fn, deref(array.Type()), e), e) } - b.assign(fn, iaddr, e, true, sb, e) - v.Bitmap.SetBit(&v.Bitmap, int(idx.Int64()), 1) - v.NumSet++ + var idx *Const + for _, e := range e.Elts { + if kv, ok := e.(*ast.KeyValueExpr); ok { + idx = b.expr(fn, kv.Key).(*Const) + e = kv.Value + } else { + var idxval int64 + if idx != nil { + idxval = idx.Int64() + 1 + } + idx = emitConst(fn, intConst(idxval)).(*Const) + } + iaddr := &IndexAddr{ + X: array, + Index: idx, + } + iaddr.setType(types.NewPointer(at.Elem())) + fn.emit(iaddr, e) + if t != at { // slice + // backing array is unaliased => storebuf not needed. + b.assign(fn, &address{addr: iaddr, expr: e}, e, true, nil, e) + } else { + b.assign(fn, &address{addr: iaddr, expr: e}, e, true, sb, e) + } + } } - final = v - fn.emit(v, e) } if t != at { // slice if final != nil { diff --git a/vendor/honnef.co/go/tools/go/ir/methods.go b/vendor/honnef.co/go/tools/go/ir/methods.go index eb247a936..b7903c847 100644 --- a/vendor/honnef.co/go/tools/go/ir/methods.go +++ b/vendor/honnef.co/go/tools/go/ir/methods.go @@ -11,8 +11,6 @@ import ( "go/types" "honnef.co/go/tools/analysis/lint" - - "golang.org/x/exp/typeparams" ) // MethodValue returns the Function implementing method sel, building @@ -118,7 +116,7 @@ func (prog *Program) RuntimeTypes() []types.Type { // declaredFunc returns the concrete function/method denoted by obj. // Panic ensues if there is none. func (prog *Program) declaredFunc(obj *types.Func) *Function { - if origin := typeparams.OriginMethod(obj); origin != obj { + if origin := obj.Origin(); origin != obj { // Calling method on instantiated type, create a wrapper that calls the generic type's method base := prog.packageLevelValue(origin) return makeInstance(prog, base.(*Function), obj.Type().(*types.Signature), nil) diff --git a/vendor/honnef.co/go/tools/go/ir/source.go b/vendor/honnef.co/go/tools/go/ir/source.go index 0aa8ef303..155c5f733 100644 --- a/vendor/honnef.co/go/tools/go/ir/source.go +++ b/vendor/honnef.co/go/tools/go/ir/source.go @@ -14,8 +14,6 @@ import ( "go/ast" "go/token" "go/types" - - "golang.org/x/exp/typeparams" ) // EnclosingFunction returns the function that contains the syntax @@ -170,7 +168,7 @@ func (prog *Program) packageLevelValue(obj types.Object) Value { // TODO(adonovan): check the invariant that obj.Type() matches the // result's Signature, both in the params/results and in the receiver. func (prog *Program) FuncValue(obj *types.Func) *Function { - obj = typeparams.OriginMethod(obj) + obj = obj.Origin() fn, _ := prog.packageLevelValue(obj).(*Function) return fn } diff --git a/vendor/honnef.co/go/tools/knowledge/deprecated.go b/vendor/honnef.co/go/tools/knowledge/deprecated.go index 343d5deb7..caeb49975 100644 --- a/vendor/honnef.co/go/tools/knowledge/deprecated.go +++ b/vendor/honnef.co/go/tools/knowledge/deprecated.go @@ -187,54 +187,44 @@ var StdlibDeprecations = map[string]Deprecation{ "syscall.Syscall18": {18, 18}, "syscall.Syscall6": {18, 18}, "syscall.Syscall9": {18, 18}, + + "reflect.SliceHeader": {21, 17}, + "reflect.StringHeader": {21, 20}, + "crypto/elliptic.GenerateKey": {21, 21}, + "crypto/elliptic.Marshal": {21, 21}, + "crypto/elliptic.Unmarshal": {21, 21}, + "(*crypto/elliptic.CurveParams).Add": {21, 21}, + "(*crypto/elliptic.CurveParams).Double": {21, 21}, + "(*crypto/elliptic.CurveParams).IsOnCurve": {21, 21}, + "(*crypto/elliptic.CurveParams).ScalarBaseMult": {21, 21}, + "(*crypto/elliptic.CurveParams).ScalarMult": {21, 21}, + "crypto/rsa.GenerateMultiPrimeKey": {21, DeprecatedNeverUse}, + "(crypto/rsa.PrecomputedValues).CRTValues": {21, DeprecatedNeverUse}, + "(crypto/x509.RevocationList).RevokedCertificates": {21, 21}, } -// Last imported from Go at 9f0234214473dfb785a5ad84a8fc62a6a395cbc3 with the following numbers of deprecations: +// Last imported from Go at c19c4c566c63818dfd059b352e52c4710eecf14d with the following numbers of deprecations: // // archive/tar/common.go:2 // archive/zip/struct.go:6 // bytes/bytes.go:1 -// cmd/api/testdata/src/pkg/p1/p1.go:8 -// cmd/api/testdata/src/pkg/p2/p2.go:2 -// cmd/api/testdata/src/pkg/p4/p4.go:1 -// cmd/compile/internal/noder/quirks.go:1 -// cmd/compile/internal/reflectdata/reflect.go:2 -// cmd/compile/internal/syntax/walk.go:1 -// cmd/compile/internal/types/sym.go:3 -// cmd/go/internal/modcmd/edit.go:1 -// cmd/go/testdata/mod/example.com_deprecated_a_v1.9.0.txt:2 -// cmd/go/testdata/mod/example.com_deprecated_b_v1.9.0.txt:2 -// cmd/go/testdata/mod/example.com_undeprecated_v1.0.0.txt:2 -// cmd/go/testdata/script/mod_deprecate_message.txt:4 -// cmd/go/testdata/script/mod_edit.txt:1 -// cmd/go/testdata/script/mod_list_deprecated.txt:2 -// cmd/go/testdata/script/mod_list_deprecated_replace.txt:1 -// cmd/internal/obj/link.go:5 -// cmd/internal/obj/textflag.go:1 -// cmd/vendor/golang.org/x/mod/modfile/rule.go:2 -// cmd/vendor/golang.org/x/mod/semver/semver.go:1 -// cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go:1 -// cmd/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go:1 -// cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go:1 -// cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go:1 -// cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go:1 -// cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm64.go:1 -// cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_riscv64.go:1 -// cmd/vendor/golang.org/x/sys/windows/security_windows.go:1 -// cmd/vendor/golang.org/x/sys/windows/syscall_windows.go:2 // compress/flate/inflate.go:2 // crypto/dsa/dsa.go:1 +// crypto/elliptic/elliptic.go:8 +// crypto/elliptic/params.go:5 // crypto/rc4/rc4.go:1 -// crypto/tls/common.go:7 +// crypto/rsa/rsa.go:2 +// crypto/tls/common.go:6 // crypto/x509/cert_pool.go:1 // crypto/x509/pem_decrypt.go:3 // crypto/x509/pkix/pkix.go:2 -// crypto/x509/x509.go:5 +// crypto/x509/x509.go:6 // database/sql/driver/driver.go:6 // debug/gosym/pclntab.go:2 // encoding/csv/reader.go:2 // encoding/json/decode.go:1 // encoding/json/encode.go:1 +// go/build/build.go:1 // go/doc/comment.go:2 // go/doc/doc.go:1 // go/doc/synopsis.go:1 @@ -260,7 +250,7 @@ var StdlibDeprecations = map[string]Deprecation{ // path/filepath/path_plan9.go:1 // path/filepath/path_unix.go:1 // path/filepath/path_windows.go:1 -// reflect/value.go:1 +// reflect/value.go:3 // regexp/regexp.go:1 // runtime/cpuprof.go:1 // strings/strings.go:1 diff --git a/vendor/honnef.co/go/tools/pattern/match.go b/vendor/honnef.co/go/tools/pattern/match.go index 32eb9d696..3eae3bd63 100644 --- a/vendor/honnef.co/go/tools/pattern/match.go +++ b/vendor/honnef.co/go/tools/pattern/match.go @@ -6,6 +6,8 @@ import ( "go/token" "go/types" "reflect" + + "golang.org/x/tools/go/ast/astutil" ) var tokensByString = map[string]Token{ @@ -560,13 +562,14 @@ func (fn Symbol) Match(m *Matcher, node interface{}) (interface{}, bool) { return nil, false } - fun := r + fun := r.(ast.Expr) switch idx := fun.(type) { case *ast.IndexExpr: fun = idx.X case *ast.IndexListExpr: fun = idx.X } + fun = astutil.Unparen(fun) switch fun := fun.(type) { case *ast.Ident: diff --git a/vendor/honnef.co/go/tools/simple/lint.go b/vendor/honnef.co/go/tools/simple/lint.go index 084264367..8458f7be6 100644 --- a/vendor/honnef.co/go/tools/simple/lint.go +++ b/vendor/honnef.co/go/tools/simple/lint.go @@ -778,13 +778,13 @@ var checkLoopAppendQ = pattern.MustParse(` x [(AssignStmt [lhs] "=" [(CallExpr (Builtin "append") [lhs val])])]) (RangeStmt - idx@(Ident _) + idx@(Object _) nil _ x [(AssignStmt [lhs] "=" [(CallExpr (Builtin "append") [lhs (IndexExpr x idx)])])]) (RangeStmt - idx@(Ident _) + idx@(Object _) nil _ x @@ -800,8 +800,7 @@ func CheckLoopAppend(pass *analysis.Pass) (interface{}, error) { return } - val, ok := m.State["val"].(types.Object) - if ok && refersTo(pass, m.State["lhs"].(ast.Expr), val) { + if val, ok := m.State["val"].(types.Object); ok && refersTo(pass, m.State["lhs"].(ast.Expr), val) { return } @@ -811,6 +810,26 @@ func CheckLoopAppend(pass *analysis.Pass) (interface{}, error) { return } + if idx, ok := m.State["idx"].(types.Object); ok && refersTo(pass, m.State["lhs"].(ast.Expr), idx) { + // The lhs mustn't refer to the index loop variable. + return + } + + if code.MayHaveSideEffects(pass, m.State["lhs"].(ast.Expr), pure) { + // The lhs may be dynamic and return different values on each iteration. For example: + // + // func bar() map[int][]int { /* return one of several maps */ } + // + // func foo(x []int, y [][]int) { + // for i := range x { + // bar()[0] = append(bar()[0], x[i]) + // } + // } + // + // The dynamic nature of the lhs might also affect the value of the index. + return + } + src := pass.TypesInfo.TypeOf(m.State["x"].(ast.Expr)) dst := pass.TypesInfo.TypeOf(m.State["lhs"].(ast.Expr)) if !types.Identical(src, dst) { diff --git a/vendor/honnef.co/go/tools/staticcheck/lint.go b/vendor/honnef.co/go/tools/staticcheck/lint.go index fb911f337..b7c0f9137 100644 --- a/vendor/honnef.co/go/tools/staticcheck/lint.go +++ b/vendor/honnef.co/go/tools/staticcheck/lint.go @@ -1144,17 +1144,31 @@ func CheckDubiousDeferInChannelRangeLoop(pass *analysis.Pass) (interface{}, erro if !ok { return } + + stmts := []*ast.DeferStmt{} + exits := false fn2 := func(node ast.Node) bool { switch stmt := node.(type) { case *ast.DeferStmt: - report.Report(pass, stmt, "defers in this range loop won't run unless the channel gets closed") + stmts = append(stmts, stmt) case *ast.FuncLit: // Don't look into function bodies return false + case *ast.ReturnStmt: + exits = true + case *ast.BranchStmt: + exits = node.(*ast.BranchStmt).Tok == token.BREAK } return true } ast.Inspect(loop.Body, fn2) + + if exits { + return + } + for _, stmt := range stmts { + report.Report(pass, stmt, "defers in this range loop won't run unless the channel gets closed") + } } code.Preorder(pass, fn, (*ast.RangeStmt)(nil)) return nil, nil @@ -1598,7 +1612,7 @@ func CheckEmptyCriticalSection(pass *analysis.Pass) (interface{}, error) { if !ok { return nil, "", false } - call, ok := expr.X.(*ast.CallExpr) + call, ok := astutil.Unparen(expr.X).(*ast.CallExpr) if !ok { return nil, "", false } @@ -3168,7 +3182,7 @@ func CheckDeprecated(pass *analysis.Pass) (interface{}, error) { obj := pass.TypesInfo.ObjectOf(sel.Sel) if obj_, ok := obj.(*types.Func); ok { - obj = typeparams.OriginMethod(obj_) + obj = obj_.Origin() } if obj.Pkg() == nil { return true diff --git a/vendor/honnef.co/go/tools/stylecheck/names.go b/vendor/honnef.co/go/tools/stylecheck/names.go index f038d0632..d37bf6baf 100644 --- a/vendor/honnef.co/go/tools/stylecheck/names.go +++ b/vendor/honnef.co/go/tools/stylecheck/names.go @@ -114,7 +114,11 @@ func CheckNames(pass *analysis.Pass) (interface{}, error) { return } - if code.IsInTest(pass, v) && (strings.HasPrefix(v.Name.Name, "Example") || strings.HasPrefix(v.Name.Name, "Test") || strings.HasPrefix(v.Name.Name, "Benchmark")) { + if code.IsInTest(pass, v) && + (strings.HasPrefix(v.Name.Name, "Example") || + strings.HasPrefix(v.Name.Name, "Test") || + strings.HasPrefix(v.Name.Name, "Benchmark") || + strings.HasPrefix(v.Name.Name, "Fuzz")) { return } diff --git a/vendor/honnef.co/go/tools/unused/unused.go b/vendor/honnef.co/go/tools/unused/unused.go index fdf6d32cb..edd263075 100644 --- a/vendor/honnef.co/go/tools/unused/unused.go +++ b/vendor/honnef.co/go/tools/unused/unused.go @@ -17,7 +17,6 @@ import ( "honnef.co/go/tools/go/ast/astutil" "honnef.co/go/tools/go/types/typeutil" - "golang.org/x/exp/typeparams" "golang.org/x/tools/go/analysis" "golang.org/x/tools/go/types/objectpath" ) @@ -1151,8 +1150,7 @@ func (g *graph) decl(decl ast.Decl, by types.Object) { } case *ast.FuncDecl: - // XXX calling OriginMethod is unnecessary if we use types.Func.Origin - obj := typeparams.OriginMethod(g.info.ObjectOf(decl.Name).(*types.Func)) + obj := g.info.ObjectOf(decl.Name).(*types.Func).Origin() g.see(obj, nil) if token.IsExported(decl.Name.Name) && g.opts.ExportedIsUsed { @@ -1332,7 +1330,7 @@ func (g *graph) stmt(stmt ast.Stmt, by types.Object) { g.read(comm.Chan, by) g.read(comm.Value, by) case *ast.ExprStmt: - g.read(comm.X.(*ast.UnaryExpr).X, by) + g.read(astutil.Unparen(comm.X).(*ast.UnaryExpr).X, by) case *ast.AssignStmt: for _, lhs := range comm.Lhs { g.write(lhs, by) diff --git a/vendor/modules.txt b/vendor/modules.txt index 25925ae56..3eef2f7d7 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -64,10 +64,10 @@ github.com/4meepo/tagalign # github.com/Abirdcfly/dupword v0.0.12 ## explicit; go 1.20 github.com/Abirdcfly/dupword -# github.com/Antonboom/errname v0.1.10 +# github.com/Antonboom/errname v0.1.12 ## explicit; go 1.20 github.com/Antonboom/errname/pkg/analyzer -# github.com/Antonboom/nilnil v0.1.5 +# github.com/Antonboom/nilnil v0.1.7 ## explicit; go 1.20 github.com/Antonboom/nilnil/pkg/analyzer # github.com/BurntSushi/toml v1.3.2 @@ -131,6 +131,17 @@ github.com/butuzov/ireturn/analyzer/internal/types ## explicit; go 1.19 github.com/butuzov/mirror github.com/butuzov/mirror/internal/checker +# github.com/ccojocar/zxcvbn-go v1.0.1 +## explicit; go 1.20 +github.com/ccojocar/zxcvbn-go +github.com/ccojocar/zxcvbn-go/adjacency +github.com/ccojocar/zxcvbn-go/data +github.com/ccojocar/zxcvbn-go/entropy +github.com/ccojocar/zxcvbn-go/frequency +github.com/ccojocar/zxcvbn-go/match +github.com/ccojocar/zxcvbn-go/matching +github.com/ccojocar/zxcvbn-go/scoring +github.com/ccojocar/zxcvbn-go/utils/math # github.com/cespare/xxhash/v2 v2.2.0 ## explicit; go 1.11 github.com/cespare/xxhash/v2 @@ -268,7 +279,7 @@ github.com/golangci/gofmt/gofmt github.com/golangci/gofmt/gofmt/internal/diff github.com/golangci/gofmt/gofmt/internal/execabs github.com/golangci/gofmt/goimports -# github.com/golangci/golangci-lint v1.54.1 +# github.com/golangci/golangci-lint v1.54.2 ## explicit; go 1.20 github.com/golangci/golangci-lint/cmd/golangci-lint github.com/golangci/golangci-lint/internal/cache @@ -512,24 +523,13 @@ github.com/moricho/tparallel/pkg/ssainstr # github.com/nakabonne/nestif v0.3.1 ## explicit; go 1.15 github.com/nakabonne/nestif -# github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 -## explicit; go 1.14 -github.com/nbutton23/zxcvbn-go -github.com/nbutton23/zxcvbn-go/adjacency -github.com/nbutton23/zxcvbn-go/data -github.com/nbutton23/zxcvbn-go/entropy -github.com/nbutton23/zxcvbn-go/frequency -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/nishanths/exhaustive v0.11.0 ## explicit; go 1.18 github.com/nishanths/exhaustive # github.com/nishanths/predeclared v0.2.2 ## explicit; go 1.14 github.com/nishanths/predeclared/passes/predeclared -# github.com/nunnatsa/ginkgolinter v0.13.3 +# github.com/nunnatsa/ginkgolinter v0.13.5 ## explicit; go 1.20 github.com/nunnatsa/ginkgolinter github.com/nunnatsa/ginkgolinter/ginkgohandler @@ -550,7 +550,7 @@ github.com/pelletier/go-toml/v2/unstable # github.com/pmezard/go-difflib v1.0.0 ## explicit github.com/pmezard/go-difflib/difflib -# github.com/polyfloyd/go-errorlint v1.4.3 +# github.com/polyfloyd/go-errorlint v1.4.4 ## explicit; go 1.20 github.com/polyfloyd/go-errorlint/errorlint # github.com/prometheus/client_golang v1.16.0 @@ -616,12 +616,12 @@ github.com/sanposhiho/wastedassign/v2 # github.com/sashamelentyev/interfacebloat v1.1.0 ## explicit; go 1.18 github.com/sashamelentyev/interfacebloat/pkg/analyzer -# github.com/sashamelentyev/usestdlibvars v1.23.0 -## explicit; go 1.19 +# github.com/sashamelentyev/usestdlibvars v1.24.0 +## explicit; go 1.20 github.com/sashamelentyev/usestdlibvars/pkg/analyzer github.com/sashamelentyev/usestdlibvars/pkg/analyzer/internal/mapping -# github.com/securego/gosec/v2 v2.16.0 -## explicit; go 1.19 +# github.com/securego/gosec/v2 v2.17.0 +## explicit; go 1.20 github.com/securego/gosec/v2 github.com/securego/gosec/v2/analyzers github.com/securego/gosec/v2/cwe @@ -700,8 +700,8 @@ github.com/t-yuki/gocover-cobertura # github.com/tdakkota/asciicheck v0.2.0 ## explicit; go 1.18 github.com/tdakkota/asciicheck -# github.com/tetafro/godot v1.4.11 -## explicit; go 1.16 +# github.com/tetafro/godot v1.4.14 +## explicit; go 1.20 github.com/tetafro/godot # github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 ## explicit; go 1.12 @@ -774,7 +774,7 @@ go.opencensus.io/trace go.opencensus.io/trace/internal go.opencensus.io/trace/propagation go.opencensus.io/trace/tracestate -# go.tmz.dev/musttag v0.7.1 +# go.tmz.dev/musttag v0.7.2 ## explicit; go 1.19 go.tmz.dev/musttag # go.uber.org/atomic v1.10.0 @@ -876,6 +876,7 @@ golang.org/x/tools/go/analysis/passes/copylock golang.org/x/tools/go/analysis/passes/ctrlflow 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 @@ -894,6 +895,7 @@ golang.org/x/tools/go/analysis/passes/reflectvaluecompare 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 @@ -1131,7 +1133,7 @@ gopkg.in/yaml.v2 # gopkg.in/yaml.v3 v3.0.1 ## explicit gopkg.in/yaml.v3 -# honnef.co/go/tools v0.4.3 +# honnef.co/go/tools v0.4.5 ## explicit; go 1.19 honnef.co/go/tools/analysis/code honnef.co/go/tools/analysis/edit |
