notary/internal/sumweb: extract hasGlobsPathPrefix from glob-matching

It will be necessary for GONOPROXY in the go command.
Having a separate function will make it easier to share the code.
(When the code moves into the go command, this function
will probably move to a different package.)

Change-Id: Idac79a40a144068b4cdf9f52f15c66d46f0f2908
Reviewed-on: https://go-review.googlesource.com/c/exp/+/173540
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
diff --git a/notary/internal/sumweb/client.go b/notary/internal/sumweb/client.go
index b42209c..25bb327 100644
--- a/notary/internal/sumweb/client.go
+++ b/notary/internal/sumweb/client.go
@@ -83,7 +83,7 @@
 	verifiers  note.Verifiers // accepted verifiers (just one, but Verifiers for note.Open)
 	tileReader tileReader
 	tileHeight int
-	noverify   []string
+	nosumdb    string
 
 	record    parCache // cache of record lookup, keyed by path@vers
 	tileCache parCache // cache of tile from client.ReadCache, keyed by tile
@@ -166,12 +166,7 @@
 // Lookup will return ErrGONOSUMDB.
 // Any call to SetGONOSUMDB must happen before the first call to Lookup.
 func (c *Conn) SetGONOSUMDB(list string) {
-	c.noverify = nil
-	for _, glob := range strings.Split(list, ",") {
-		if glob != "" {
-			c.noverify = append(c.noverify, glob)
-		}
-	}
+	c.nosumdb = list
 }
 
 // ErrGONOSUMDB is returned by Lookup for paths that match
@@ -180,7 +175,26 @@
 var ErrGONOSUMDB = errors.New("skipped (listed in GONOSUMDB)")
 
 func (c *Conn) skip(target string) bool {
-	for _, glob := range c.noverify {
+	return hasGlobsPathPrefix(c.nosumdb, target)
+}
+
+// hasGlobsPathPrefix reports whether any path prefix of target
+// matches one of the glob patterns (as defined by path.Match)
+// in the comma-separated globs list.
+// It ignores any empty or malformed patterns in the list.
+func hasGlobsPathPrefix(globs, target string) bool {
+	for globs != "" {
+		// Extract next non-empty glob in comma-separated list.
+		var glob string
+		if i := strings.Index(globs, ","); i >= 0 {
+			glob, globs = globs[:i], globs[i+1:]
+		} else {
+			glob, globs = globs, ""
+		}
+		if glob == "" {
+			continue
+		}
+
 		// A glob with N+1 path elements (N slashes) needs to be matched
 		// against the first N+1 path elements of target,
 		// which end just before the N+1'th slash.