github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/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 "regexp" 8 "strings" 9 ) 10 11 type PathMatcher struct { 12 matches []*match 13 } 14 15 type match struct { 16 include *regexp.Regexp 17 exclude *regexp.Regexp 18 object *Subsystem 19 } 20 21 func MakePathMatcher(list []*Subsystem) *PathMatcher { 22 m := &PathMatcher{} 23 for _, item := range list { 24 m.register(item) 25 } 26 return m 27 } 28 29 func (p *PathMatcher) register(item *Subsystem) { 30 onlyInclude := []string{} 31 list := []PathRule{} 32 for _, r := range item.PathRules { 33 if r.ExcludeRegexp == "" { 34 // It's expected that almost everything will go to this branch. 35 onlyInclude = append(onlyInclude, r.IncludeRegexp) 36 } else { 37 list = append(list, r) 38 } 39 } 40 if len(onlyInclude) > 0 { 41 list = append(list, PathRule{ 42 IncludeRegexp: strings.Join(onlyInclude, "|"), 43 }) 44 } 45 for _, rule := range list { 46 p.matches = append(p.matches, buildMatch(rule, item)) 47 } 48 } 49 50 func (p *PathMatcher) Match(path string) []*Subsystem { 51 ret := []*Subsystem{} 52 for _, m := range p.matches { 53 if m.exclude != nil && m.exclude.MatchString(path) { 54 continue 55 } 56 if m.include != nil && !m.include.MatchString(path) { 57 continue 58 } 59 ret = append(ret, m.object) 60 } 61 return ret 62 } 63 64 func buildMatch(rule PathRule, item *Subsystem) *match { 65 m := &match{object: item} 66 if rule.IncludeRegexp != "" { 67 m.include = regexp.MustCompile(rule.IncludeRegexp) 68 } 69 if rule.ExcludeRegexp != "" { 70 m.exclude = regexp.MustCompile(rule.ExcludeRegexp) 71 } 72 return m 73 }