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  }