Matching
The CPE library provides sophisticated matching capabilities for comparing CPE objects, including basic matching, advanced matching with various algorithms, and version comparison.
Basic Matching
CPE.Match
func (c *CPE) Match(other *CPE) bool
Performs basic CPE matching according to the CPE Name Matching specification.
Parameters:
other
- The CPE to match against
Returns:
bool
-true
if the CPEs match,false
otherwise
Matching Rules:
- If CPE URIs are identical, return
true
- Part must match exactly
- For other attributes:
- If either value is wildcard (
*
), they match - If both values are "not applicable" (
-
), they match - Otherwise, values must be exactly equal
- If either value is wildcard (
Example:
// Create CPEs
windows10, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
windowsPattern, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:*:*:*:*:*:*:*:*")
// Test matching
if windowsPattern.Match(windows10) {
fmt.Println("Windows 10 matches the Windows pattern")
}
// Test non-matching
office, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:office:2019:*:*:*:*:*:*:*")
if !windowsPattern.Match(office) {
fmt.Println("Office does not match the Windows pattern")
}
MatchCPE
func MatchCPE(cpe1, cpe2 *CPE, options *MatchOptions) bool
Performs CPE matching with configurable options.
Parameters:
cpe1
- First CPE to comparecpe2
- Second CPE to compareoptions
- Matching options (can benil
for defaults)
Returns:
bool
-true
if the CPEs match according to the options
MatchOptions
type MatchOptions struct {
IgnoreVersion bool // Ignore version field in matching
IgnoreUpdate bool // Ignore update field in matching
CaseSensitive bool // Case-sensitive string comparison
}
Example:
// Create match options
options := &cpe.MatchOptions{
IgnoreVersion: true,
CaseSensitive: false,
}
cpe1, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
cpe2, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:11:*:*:*:*:*:*:*")
// Match ignoring version
if cpe.MatchCPE(cpe1, cpe2, options) {
fmt.Println("CPEs match when ignoring version")
}
DefaultMatchOptions
func DefaultMatchOptions() *MatchOptions
Returns default matching options.
Returns:
*MatchOptions
- Default options with all flags set tofalse
Advanced Matching
AdvancedMatchCPE
func AdvancedMatchCPE(criteria *CPE, target *CPE, options *AdvancedMatchOptions) bool
Performs advanced CPE matching with sophisticated algorithms.
Parameters:
criteria
- CPE pattern to match againsttarget
- CPE to test for matchingoptions
- Advanced matching options
Returns:
bool
-true
if the target matches the criteria
AdvancedMatchOptions
type AdvancedMatchOptions struct {
UseRegex bool // Enable regex matching
IgnoreCase bool // Case-insensitive matching
UseFuzzyMatch bool // Enable fuzzy matching
MatchCommonOnly bool // Match only common fields
PartialMatch bool // Enable partial matching
MatchMode string // Matching mode
VersionCompareMode string // Version comparison mode
VersionLower string // Version lower bound
VersionUpper string // Version upper bound
FieldOptions map[string]FieldMatchOption // Field-specific options
ScoreThreshold float64 // Minimum match score (0.0-1.0)
}
FieldMatchOption
type FieldMatchOption struct {
Weight float64 // Field weight (0.0-1.0)
Required bool // Whether field must match
MatchMethod string // Matching method for this field
}
NewAdvancedMatchOptions
func NewAdvancedMatchOptions() *AdvancedMatchOptions
Creates default advanced matching options.
Returns:
*AdvancedMatchOptions
- Default advanced options
Example:
// Create advanced matching options
options := cpe.NewAdvancedMatchOptions()
options.MatchMode = "distance"
options.ScoreThreshold = 0.8
options.IgnoreCase = true
// Set field-specific options
options.FieldOptions = map[string]cpe.FieldMatchOption{
"vendor": {
Weight: 1.0,
Required: true,
},
"product": {
Weight: 1.0,
Required: true,
},
"version": {
Weight: 0.7,
Required: false,
},
}
criteria, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:*:*:*:*:*:*:*:*:*")
target, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
if cpe.AdvancedMatchCPE(criteria, target, options) {
fmt.Println("Advanced match successful")
}
Match Modes
Exact Mode
Performs exact field matching with special value handling.
options := cpe.NewAdvancedMatchOptions()
options.MatchMode = "exact"
Subset Mode
Checks if the target is a subset of the criteria.
options := cpe.NewAdvancedMatchOptions()
options.MatchMode = "subset"
Superset Mode
Checks if the target is a superset of the criteria.
options := cpe.NewAdvancedMatchOptions()
options.MatchMode = "superset"
Distance Mode
Uses similarity scoring to determine matches.
options := cpe.NewAdvancedMatchOptions()
options.MatchMode = "distance"
options.ScoreThreshold = 0.7 // Require 70% similarity
Version Comparison
CompareVersionsString
func CompareVersionsString(v1, v2 string) int
Compares two version strings.
Parameters:
v1
- First version stringv2
- Second version string
Returns:
int
--1
if v1 < v2,0
if v1 == v2,1
if v1 > v2
Example:
result := cpe.CompareVersionsString("1.0.0", "1.0.1")
fmt.Printf("Comparison result: %d\n", result) // -1
result = cpe.CompareVersionsString("2.0", "1.9.9")
fmt.Printf("Comparison result: %d\n", result) // 1
result = cpe.CompareVersionsString("1.0", "1.0.0")
fmt.Printf("Comparison result: %d\n", result) // 0
Version Range Matching
Advanced matching supports version range comparisons:
options := cpe.NewAdvancedMatchOptions()
options.VersionCompareMode = "range"
options.VersionLower = "1.0"
options.VersionUpper = "2.0"
// This will match versions between 1.0 and 2.0
criteria, _ := cpe.ParseCpe23("cpe:2.3:a:vendor:product:*:*:*:*:*:*:*:*")
target, _ := cpe.ParseCpe23("cpe:2.3:a:vendor:product:1.5:*:*:*:*:*:*:*")
if cpe.AdvancedMatchCPE(criteria, target, options) {
fmt.Println("Version is within range")
}
Regex Matching
Enable regular expression matching for flexible pattern matching:
options := cpe.NewAdvancedMatchOptions()
options.UseRegex = true
// Use regex patterns in CPE fields
criteria, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:.*office.*:*:*:*:*:*:*:*:*")
target, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:ms_office:2019:*:*:*:*:*:*:*")
if cpe.AdvancedMatchCPE(criteria, target, options) {
fmt.Println("Regex match successful")
}
Fuzzy Matching
Enable fuzzy matching for approximate string matching:
options := cpe.NewAdvancedMatchOptions()
options.UseFuzzyMatch = true
options.ScoreThreshold = 0.8
// This might match even with slight spelling differences
criteria, _ := cpe.ParseCpe23("cpe:2.3:a:apache:tomcat:*:*:*:*:*:*:*:*")
target, _ := cpe.ParseCpe23("cpe:2.3:a:apache:tomkat:8.5:*:*:*:*:*:*:*") // Note: "tomkat" vs "tomcat"
if cpe.AdvancedMatchCPE(criteria, target, options) {
fmt.Println("Fuzzy match successful")
}
Complete Example
package main
import (
"fmt"
"log"
"github.com/scagogogo/cpe"
)
func main() {
// Parse CPEs
pattern, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:*:*:*:*:*:*:*:*:*")
windows10, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
office2019, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:office:2019:*:*:*:*:*:*:*")
// Basic matching
fmt.Println("=== Basic Matching ===")
fmt.Printf("Pattern matches Windows 10: %t\n", pattern.Match(windows10))
fmt.Printf("Pattern matches Office 2019: %t\n", pattern.Match(office2019))
// Advanced matching with distance mode
fmt.Println("\n=== Advanced Matching ===")
options := cpe.NewAdvancedMatchOptions()
options.MatchMode = "distance"
options.ScoreThreshold = 0.7
fmt.Printf("Advanced match Windows 10: %t\n",
cpe.AdvancedMatchCPE(pattern, windows10, options))
fmt.Printf("Advanced match Office 2019: %t\n",
cpe.AdvancedMatchCPE(pattern, office2019, options))
// Version comparison
fmt.Println("\n=== Version Comparison ===")
fmt.Printf("1.0 vs 1.1: %d\n", cpe.CompareVersionsString("1.0", "1.1"))
fmt.Printf("2.0 vs 1.9: %d\n", cpe.CompareVersionsString("2.0", "1.9"))
fmt.Printf("1.0 vs 1.0: %d\n", cpe.CompareVersionsString("1.0", "1.0"))
// Regex matching
fmt.Println("\n=== Regex Matching ===")
regexOptions := cpe.NewAdvancedMatchOptions()
regexOptions.UseRegex = true
regexPattern, _ := cpe.ParseCpe23("cpe:2.3:a:.*soft.*:.*:*:*:*:*:*:*:*:*")
fmt.Printf("Regex pattern matches Windows: %t\n",
cpe.AdvancedMatchCPE(regexPattern, windows10, regexOptions))
}