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) boolPerforms basic CPE matching according to the CPE Name Matching specification.
Parameters:
other- The CPE to match against
Returns:
bool-trueif the CPEs match,falseotherwise
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) boolPerforms CPE matching with configurable options.
Parameters:
cpe1- First CPE to comparecpe2- Second CPE to compareoptions- Matching options (can benilfor defaults)
Returns:
bool-trueif 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() *MatchOptionsReturns default matching options.
Returns:
*MatchOptions- Default options with all flags set tofalse
Advanced Matching
AdvancedMatchCPE
func AdvancedMatchCPE(criteria *CPE, target *CPE, options *AdvancedMatchOptions) boolPerforms advanced CPE matching with sophisticated algorithms.
Parameters:
criteria- CPE pattern to match againsttarget- CPE to test for matchingoptions- Advanced matching options
Returns:
bool-trueif 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() *AdvancedMatchOptionsCreates 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% similarityVersion Comparison
CompareVersionsString
func CompareVersionsString(v1, v2 string) intCompares two version strings.
Parameters:
v1- First version stringv2- Second version string
Returns:
int--1if v1 < v2,0if v1 == v2,1if 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) // 0Version 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))
}