in tool/preprocess/match.go [175:223]
func matchVersion(version string, ruleVersion string) (bool, error) {
// Fast path, always match if the rule version is not specified
if ruleVersion == "" {
return true, nil
}
// Check if both rule version and package version are in sane
if !strings.Contains(version, "v") {
return false, errc.New(errc.ErrMatchRule,
fmt.Sprintf("invalid version %v", version))
}
if !strings.Contains(ruleVersion, "[") ||
!strings.Contains(ruleVersion, ")") ||
!strings.Contains(ruleVersion, ",") ||
strings.Contains(ruleVersion, "v") {
return false, errc.New(errc.ErrMatchRule,
fmt.Sprintf("invalid rule version %v", ruleVersion))
}
// Remove extra whitespace from the rule version string
ruleVersion = strings.ReplaceAll(ruleVersion, " ", "")
// Compare the version with the rule version, the rule version is in the
// format [start, end), where start is inclusive and end is exclusive
// and start or end can be omitted, which means the range is open-ended.
ruleVersionStart, ruleVersionEnd := splitVersionRange(ruleVersion)
switch {
case ruleVersionStart != "v" && ruleVersionEnd != "v":
// Full version range
if semver.Compare(version, ruleVersionStart) >= 0 &&
semver.Compare(version, ruleVersionEnd) < 0 {
return true, nil
}
case ruleVersionStart == "v":
// Only end is specified
util.Assert(ruleVersionEnd != "v", "sanity check")
if semver.Compare(version, ruleVersionEnd) < 0 {
return true, nil
}
case ruleVersionEnd == "v":
// Only start is specified
util.Assert(ruleVersionStart != "v", "sanity check")
if semver.Compare(version, ruleVersionStart) >= 0 {
return true, nil
}
default:
return false, errc.New(errc.ErrMatchRule,
fmt.Sprintf("invalid rule version range %v", ruleVersion))
}
return false, nil
}