From 68ba75078b8204b7cd3d11f9a4a43c60b2a8d82f Mon Sep 17 00:00:00 2001 From: Marwan Sulaiman Date: Fri, 20 Sep 2019 12:17:03 -0400 Subject: [PATCH] proxy/actions/sumdb: copy Go behavior for pattern matching (#1388) --- cmd/proxy/actions/sumdb.go | 28 +++++++++++++++++++++++++++- cmd/proxy/actions/sumdb_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/cmd/proxy/actions/sumdb.go b/cmd/proxy/actions/sumdb.go index 95ca49aea..6fdd0e11a 100644 --- a/cmd/proxy/actions/sumdb.go +++ b/cmd/proxy/actions/sumdb.go @@ -25,7 +25,7 @@ func noSumWrapper(h http.Handler, host string, patterns []string) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if strings.HasPrefix(r.URL.Path, "/lookup/") { for _, p := range patterns { - if isMatch, err := path.Match(p, r.URL.Path[len("/lookup/"):]); err == nil && isMatch { + if matchesPattern(p, r.URL.Path[len("/lookup/"):]) { w.WriteHeader(http.StatusForbidden) return } @@ -34,3 +34,29 @@ func noSumWrapper(h http.Handler, host string, patterns []string) http.Handler { h.ServeHTTP(w, r) }) } + +// matchesPattern is adopted from +// https://github.com/golang/go/blob/a11644a26557ea436d456f005f39f4e01902bafe/src/cmd/go/internal/str/path.go#L58 +// this function matches based on path prefixes and +// tries to keep the same behavior as GONOSUMDB and friends +func matchesPattern(pattern, target string) bool { + n := strings.Count(pattern, "/") + prefix := target + for i := 0; i < len(target); i++ { + if target[i] == '/' { + if n == 0 { + prefix = target[:i] + break + } + n-- + } + } + if n > 0 { + return false + } + matched, _ := path.Match(pattern, prefix) + if matched { + return true + } + return false +} diff --git a/cmd/proxy/actions/sumdb_test.go b/cmd/proxy/actions/sumdb_test.go index e8239cdf2..7b6687188 100644 --- a/cmd/proxy/actions/sumdb_test.go +++ b/cmd/proxy/actions/sumdb_test.go @@ -61,6 +61,30 @@ var noSumTestCases = []struct { "github.com/private/repo@v0.0.1", http.StatusForbidden, }, + { + "multi slash star", + []string{"github.com/private/*"}, + "github.com/private/repo/sub@v0.0.1", + http.StatusForbidden, + }, + { + "multi star", + []string{"github.com/*/*"}, + "github.com/private/repo@v0.0.1", + http.StatusForbidden, + }, + { + "multi star ok", + []string{"github.com/private/*/*"}, + "github.com/private/repo@v0.0.1", + http.StatusOK, + }, + { + "multi star forbidden", + []string{"github.com/private/*/*"}, + "github.com/private/repo/sub@v0.0.1", + http.StatusForbidden, + }, { "any version", []string{"github.com/private/repo*"},