mirror of
https://github.com/anchore/syft.git
synced 2026-10-30 14:02:26 +01:00
migrate filename glob helpers to internal
Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
@@ -2,7 +2,6 @@ package archive
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
@@ -49,7 +48,7 @@ func (z ZipFileManifest) GlobMatch(patterns ...string) []string {
|
||||
// so that glob logic is consistent inside and outside of ZIP archives
|
||||
normalizedEntry := normalizeZipEntryName(entry)
|
||||
|
||||
if file.GlobMatch(pattern, normalizedEntry) {
|
||||
if internal.FileNameGlobMatch(pattern, normalizedEntry) {
|
||||
uniqueMatches.Add(entry)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package internal
|
||||
|
||||
// FileNameGlobMatch evaluates the given glob pattern against the given "name" string, indicating if there is a match or not.
|
||||
// Source: https://research.swtch.com/glob.go
|
||||
func FileNameGlobMatch(pattern, name string) bool {
|
||||
px := 0
|
||||
nx := 0
|
||||
nextPx := 0
|
||||
nextNx := 0
|
||||
for px < len(pattern) || nx < len(name) {
|
||||
if px < len(pattern) {
|
||||
c := pattern[px]
|
||||
switch c {
|
||||
default: // ordinary character
|
||||
if nx < len(name) && name[nx] == c {
|
||||
px++
|
||||
nx++
|
||||
continue
|
||||
}
|
||||
case '?': // single-character wildcard
|
||||
if nx < len(name) {
|
||||
px++
|
||||
nx++
|
||||
continue
|
||||
}
|
||||
case '*': // zero-or-more-character wildcard
|
||||
// Try to match at nx.
|
||||
// If that doesn't work out,
|
||||
// restart at nx+1 next.
|
||||
nextPx = px
|
||||
nextNx = nx + 1
|
||||
px++
|
||||
continue
|
||||
}
|
||||
}
|
||||
// Mismatch. Maybe restart.
|
||||
if 0 < nextNx && nextNx <= len(name) {
|
||||
px = nextPx
|
||||
nx = nextNx
|
||||
continue
|
||||
}
|
||||
return false
|
||||
}
|
||||
// Matched all of pattern to all of name. Success.
|
||||
return true
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGlobMatch(t *testing.T) {
|
||||
var tests = []struct {
|
||||
pattern string
|
||||
data string
|
||||
ok bool
|
||||
}{
|
||||
{"", "", true},
|
||||
{"x", "", false},
|
||||
{"", "x", false},
|
||||
{"abc", "abc", true},
|
||||
{"*", "abc", true},
|
||||
{"*c", "abc", true},
|
||||
{"*b", "abc", false},
|
||||
{"a*", "abc", true},
|
||||
{"b*", "abc", false},
|
||||
{"a*", "a", true},
|
||||
{"*a", "a", true},
|
||||
{"a*b*c*d*e*", "axbxcxdxe", true},
|
||||
{"a*b*c*d*e*", "axbxcxdxexxx", true},
|
||||
{"a*b?c*x", "abxbbxdbxebxczzx", true},
|
||||
{"a*b?c*x", "abxbbxdbxebxczzy", false},
|
||||
{"a*a*a*a*b", strings.Repeat("a", 100), false},
|
||||
{"*x", "xxx", true},
|
||||
{"/home/place/**", "/home/place/a/thing", true},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
if FileNameGlobMatch(test.pattern, test.data) != test.ok {
|
||||
t.Errorf("failed glob='%s' data='%s'", test.pattern, test.data)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user