aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/stbenjam
diff options
context:
space:
mode:
authorTaras Madan <tarasmadan@google.com>2022-09-05 14:27:54 +0200
committerGitHub <noreply@github.com>2022-09-05 12:27:54 +0000
commitb2f2446b46bf02821d90ebedadae2bf7ae0e880e (patch)
tree923cf42842918d6bebca1d6bbdc08abed54d274d /vendor/github.com/stbenjam
parente6654faff4bcca4be92e9a8596fd4b77f747c39e (diff)
go.mod, vendor: update (#3358)
* go.mod, vendor: remove unnecessary dependencies Commands: 1. go mod tidy 2. go mod vendor * go.mod, vendor: update cloud.google.com/go Commands: 1. go get -u cloud.google.com/go 2. go mod tidy 3. go mod vendor * go.mod, vendor: update cloud.google.com/* Commands: 1. go get -u cloud.google.com/storage cloud.google.com/logging 2. go mod tidy 3. go mod vendor * go.mod, .golangci.yml, vendor: update *lint* Commands: 1. go get -u golang.org/x/tools github.com/golangci/golangci-lint@v1.47.0 2. go mod tidy 3. go mod vendor 4. edit .golangci.yml to suppress new errors (resolved in the same PR later) * all: fix lint errors hash.go: copy() recommended by gosimple parse.go: ent is never nil verifier.go: signal.Notify() with unbuffered channel is bad. Have no idea why. * .golangci.yml: adjust godot rules check-all is deprecated, but still work if you're hesitating too - I'll remove this commit
Diffstat (limited to 'vendor/github.com/stbenjam')
-rw-r--r--vendor/github.com/stbenjam/no-sprintf-host-port/LICENSE21
-rw-r--r--vendor/github.com/stbenjam/no-sprintf-host-port/pkg/analyzer/analyzer.go96
2 files changed, 117 insertions, 0 deletions
diff --git a/vendor/github.com/stbenjam/no-sprintf-host-port/LICENSE b/vendor/github.com/stbenjam/no-sprintf-host-port/LICENSE
new file mode 100644
index 000000000..586dfd8cc
--- /dev/null
+++ b/vendor/github.com/stbenjam/no-sprintf-host-port/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 Stephen Benjamin
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE. \ No newline at end of file
diff --git a/vendor/github.com/stbenjam/no-sprintf-host-port/pkg/analyzer/analyzer.go b/vendor/github.com/stbenjam/no-sprintf-host-port/pkg/analyzer/analyzer.go
new file mode 100644
index 000000000..374bb0d24
--- /dev/null
+++ b/vendor/github.com/stbenjam/no-sprintf-host-port/pkg/analyzer/analyzer.go
@@ -0,0 +1,96 @@
+package analyzer
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+ "regexp"
+
+ "golang.org/x/tools/go/analysis/passes/inspect"
+ "golang.org/x/tools/go/ast/inspector"
+
+ "golang.org/x/tools/go/analysis"
+)
+
+var Analyzer = &analysis.Analyzer{
+ Name: "nosprintfhostport",
+ Doc: "Checks for misuse of Sprintf to construct a host with port in a URL.",
+ Run: run,
+ Requires: []*analysis.Analyzer{inspect.Analyzer},
+}
+
+func run(pass *analysis.Pass) (interface{}, error) {
+ inspector := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
+ nodeFilter := []ast.Node{
+ (*ast.CallExpr)(nil),
+ }
+
+ inspector.Preorder(nodeFilter, func(node ast.Node) {
+ callExpr := node.(*ast.CallExpr)
+ if p, f, ok := getCallExprFunction(callExpr); ok && p == "fmt" && f == "Sprintf" {
+ if err := checkForHostPortConstruction(callExpr); err != nil {
+ pass.Reportf(node.Pos(), err.Error())
+ }
+ }
+ })
+
+ return nil, nil
+}
+
+// getCallExprFunction returns the package and function name from a callExpr, if any.
+func getCallExprFunction(callExpr *ast.CallExpr) (pkg string, fn string, result bool) {
+ selector, ok := callExpr.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return "", "", false
+ }
+ gopkg, ok := selector.X.(*ast.Ident)
+ if !ok {
+ return "", "", false
+ }
+ return gopkg.Name, selector.Sel.Name, true
+}
+
+// getStringLiteral returns the value at a position if it's a string literal.
+func getStringLiteral(args []ast.Expr, pos int) (string, bool) {
+ if len(args) < pos + 1 {
+ return "", false
+ }
+
+ // Let's see if our format string is a string literal.
+ fsRaw, ok := args[pos].(*ast.BasicLit)
+ if !ok {
+ return "", false
+ }
+ if fsRaw.Kind == token.STRING && len(fsRaw.Value) >= 2 {
+ return fsRaw.Value[1 : len(fsRaw.Value)-1], true
+ } else {
+ return "", false
+ }
+}
+
+// checkForHostPortConstruction checks to see if a sprintf call looks like a URI with a port,
+// essentially scheme://%s:<something else>, or scheme://user:pass@%s:<something else>.
+//
+// Matching requirements:
+// - Scheme as per RFC3986 is ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+// - A format string substitution in the host portion, preceded by an optional username/password@
+// - A colon indicating a port will be specified
+func checkForHostPortConstruction(sprintf *ast.CallExpr) error {
+ fs, ok := getStringLiteral(sprintf.Args, 0)
+ if !ok {
+ return nil
+ }
+
+ regexes := []*regexp.Regexp{
+ regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9+-.]*://%s:[^@]*$`), // URL without basic auth user
+ regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9+-.]*://[^/]*@%s:.*$`), // URL with basic auth
+ }
+
+ for _, re := range regexes {
+ if re.MatchString(fs) {
+ return fmt.Errorf("host:port in url should be constructed with net.JoinHostPort and not directly with fmt.Sprintf")
+ }
+ }
+
+ return nil
+} \ No newline at end of file