Abstract property value matching logic behind an interface

Make it easy to add additional ways of matching property values. Needed
to add support for a 'starts with' matcher that can be used to restrict
allowable values in include_dir.

Test: m nothing
Bug: 35624006
Change-Id: I82e7d95f08847bf294aac311968e1d9f3e4b385d
This commit is contained in:
Paul Duffin
2019-07-12 14:12:49 +01:00
parent 60c0cd9a5f
commit 73bf054a52

View File

@@ -156,9 +156,39 @@ func neverallowMutator(ctx BottomUpMutatorContext) {
} }
} }
type ValueMatcher interface {
test(string) bool
String() string
}
type equalMatcher struct {
expected string
}
func (m *equalMatcher) test(value string) bool {
return m.expected == value
}
func (m *equalMatcher) String() string {
return "=" + m.expected
}
type anyMatcher struct {
}
func (m *anyMatcher) test(value string) bool {
return true
}
func (m *anyMatcher) String() string {
return "=*"
}
var anyMatcherInstance = &anyMatcher{}
type ruleProperty struct { type ruleProperty struct {
fields []string // e.x.: Vndk.Enabled fields []string // e.x.: Vndk.Enabled
value string // e.x.: true matcher ValueMatcher
} }
// A NeverAllow rule. // A NeverAllow rule.
@@ -219,20 +249,27 @@ func (r *rule) NotModuleType(types ...string) Rule {
func (r *rule) With(properties, value string) Rule { func (r *rule) With(properties, value string) Rule {
r.props = append(r.props, ruleProperty{ r.props = append(r.props, ruleProperty{
fields: fieldNamesForProperties(properties), fields: fieldNamesForProperties(properties),
value: value, matcher: selectMatcher(value),
}) })
return r return r
} }
func (r *rule) Without(properties, value string) Rule { func (r *rule) Without(properties, value string) Rule {
r.unlessProps = append(r.unlessProps, ruleProperty{ r.unlessProps = append(r.unlessProps, ruleProperty{
fields: fieldNamesForProperties(properties), fields: fieldNamesForProperties(properties),
value: value, matcher: selectMatcher(value),
}) })
return r return r
} }
func selectMatcher(expected string) ValueMatcher {
if expected == "*" {
return anyMatcherInstance
}
return &equalMatcher{expected: expected}
}
func (r *rule) Because(reason string) Rule { func (r *rule) Because(reason string) Rule {
r.reason = reason r.reason = reason
return r return r
@@ -253,10 +290,10 @@ func (r *rule) String() string {
s += " -type:" + v s += " -type:" + v
} }
for _, v := range r.props { for _, v := range r.props {
s += " " + strings.Join(v.fields, ".") + "=" + v.value s += " " + strings.Join(v.fields, ".") + v.matcher.String()
} }
for _, v := range r.unlessProps { for _, v := range r.unlessProps {
s += " -" + strings.Join(v.fields, ".") + "=" + v.value s += " -" + strings.Join(v.fields, ".") + v.matcher.String()
} }
if len(r.reason) != 0 { if len(r.reason) != 0 {
s += " which is restricted because " + r.reason s += " which is restricted because " + r.reason
@@ -338,8 +375,8 @@ func hasProperty(properties []interface{}, prop ruleProperty) bool {
continue continue
} }
check := func(v string) bool { check := func(value string) bool {
return prop.value == "*" || prop.value == v return prop.matcher.test(value)
} }
if matchValue(propertiesValue, check) { if matchValue(propertiesValue, check) {