github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/pkg/subsystem/match.go (about) 1 // Copyright 2023 syzkaller project authors. All rights reserved. 2 // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 3 4 package subsystem 5 6 import ( 7 "maps" 8 "regexp" 9 "slices" 10 "strings" 11 ) 12 13 type PathMatcher struct { 14 matches []*match 15 } 16 17 type match struct { 18 include *regexp.Regexp 19 exclude *regexp.Regexp 20 object *Subsystem 21 } 22 23 func MakePathMatcher(list []*Subsystem) *PathMatcher { 24 m := &PathMatcher{} 25 for _, item := range list { 26 m.register(item) 27 } 28 return m 29 } 30 31 func (p *PathMatcher) register(item *Subsystem) { 32 onlyInclude := []string{} 33 list := []PathRule{} 34 for _, r := range item.PathRules { 35 if r.ExcludeRegexp == "" { 36 // It's expected that almost everything will go to this branch. 37 onlyInclude = append(onlyInclude, r.IncludeRegexp) 38 } else { 39 list = append(list, r) 40 } 41 } 42 if len(onlyInclude) > 0 { 43 list = append(list, PathRule{ 44 IncludeRegexp: strings.Join(onlyInclude, "|"), 45 }) 46 } 47 for _, rule := range list { 48 p.matches = append(p.matches, buildMatch(rule, item)) 49 } 50 } 51 52 func (p *PathMatcher) Match(path string) []*Subsystem { 53 ret := map[*Subsystem]struct{}{} 54 for _, m := range p.matches { 55 if m.exclude != nil && m.exclude.MatchString(path) { 56 continue 57 } 58 if m.include != nil && !m.include.MatchString(path) { 59 continue 60 } 61 ret[m.object] = struct{}{} 62 } 63 return slices.Collect(maps.Keys(ret)) 64 } 65 66 func buildMatch(rule PathRule, item *Subsystem) *match { 67 m := &match{object: item} 68 if rule.IncludeRegexp != "" { 69 m.include = regexp.MustCompile(rule.IncludeRegexp) 70 } 71 if rule.ExcludeRegexp != "" { 72 m.exclude = regexp.MustCompile(rule.ExcludeRegexp) 73 } 74 return m 75 }