Sets
The CPE library provides powerful set operations for managing collections of CPE objects, including union, intersection, difference, and advanced filtering capabilities.
CPESet Structure
CPESet
type CPESet struct {
// Internal implementation details are hidden
}The CPESet type represents a collection of unique CPE objects with efficient set operations.
Creating Sets
NewCPESet
func NewCPESet() *CPESetCreates a new empty CPE set.
Returns:
*CPESet- New empty set
Example:
// Create a new empty set
set := cpe.NewCPESet()
fmt.Printf("Created empty set with %d items\n", set.Size())FromArray
func FromArray(cpes []*CPE) *CPESetCreates a CPE set from an array of CPE objects.
Parameters:
cpes- Array of CPE objects
Returns:
*CPESet- Set containing the CPE objects
Example:
// Create CPEs
cpe1, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
cpe2, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:office:2019:*:*:*:*:*:*:*")
cpe3, _ := cpe.ParseCpe23("cpe:2.3:a:apache:tomcat:9.0:*:*:*:*:*:*:*")
// Create set from array
cpeArray := []*cpe.CPE{cpe1, cpe2, cpe3}
set := cpe.FromArray(cpeArray)
fmt.Printf("Created set with %d items\n", set.Size())FromStrings
func FromStrings(cpeStrings []string) (*CPESet, error)Creates a CPE set from an array of CPE strings.
Parameters:
cpeStrings- Array of CPE string representations
Returns:
*CPESet- Set containing parsed CPE objectserror- Error if any string fails to parse
Example:
cpeStrings := []string{
"cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*",
"cpe:2.3:a:apache:tomcat:9.0:*:*:*:*:*:*:*",
"cpe:2.3:o:linux:kernel:5.4:*:*:*:*:*:*:*",
}
set, err := cpe.FromStrings(cpeStrings)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Created set from strings with %d items\n", set.Size())Basic Operations
Add
func (s *CPESet) Add(cpes ...*CPE) *CPESetAdds one or more CPE objects to the set.
Parameters:
cpes- Variable number of CPE objects to add
Returns:
*CPESet- The set itself (for method chaining)
Example:
set := cpe.NewCPESet()
cpe1, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
cpe2, _ := cpe.ParseCpe23("cpe:2.3:a:apache:tomcat:9.0:*:*:*:*:*:*:*")
// Add single CPE
set.Add(cpe1)
// Add multiple CPEs
set.Add(cpe2, cpe1) // cpe1 won't be added again (sets contain unique items)
fmt.Printf("Set size after adding: %d\n", set.Size())Remove
func (s *CPESet) Remove(cpe *CPE) boolRemoves a CPE object from the set.
Parameters:
cpe- CPE object to remove
Returns:
bool-trueif the CPE was removed,falseif it wasn't in the set
Example:
cpe1, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
set := cpe.NewCPESet()
set.Add(cpe1)
removed := set.Remove(cpe1)
fmt.Printf("CPE removed: %t\n", removed)
fmt.Printf("Set size after removal: %d\n", set.Size())Contains
func (s *CPESet) Contains(cpe *CPE) boolChecks if the set contains a specific CPE object.
Parameters:
cpe- CPE object to check for
Returns:
bool-trueif the set contains the CPE,falseotherwise
Example:
cpe1, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
cpe2, _ := cpe.ParseCpe23("cpe:2.3:a:apache:tomcat:9.0:*:*:*:*:*:*:*")
set := cpe.NewCPESet()
set.Add(cpe1)
fmt.Printf("Contains Windows: %t\n", set.Contains(cpe1))
fmt.Printf("Contains Tomcat: %t\n", set.Contains(cpe2))Size
func (s *CPESet) Size() intReturns the number of CPE objects in the set.
Returns:
int- Number of items in the set
IsEmpty
func (s *CPESet) IsEmpty() boolChecks if the set is empty.
Returns:
bool-trueif the set is empty,falseotherwise
Clear
func (s *CPESet) Clear()Removes all CPE objects from the set.
Example:
set := cpe.NewCPESet()
// ... add some CPEs ...
fmt.Printf("Size before clear: %d\n", set.Size())
set.Clear()
fmt.Printf("Size after clear: %d\n", set.Size())
fmt.Printf("Is empty: %t\n", set.IsEmpty())Set Operations
Union
func (s *CPESet) Union(other *CPESet) *CPESetReturns a new set containing all CPEs from both sets.
Parameters:
other- Another CPE set
Returns:
*CPESet- New set containing union of both sets
Example:
// Create two sets
set1 := cpe.NewCPESet()
set2 := cpe.NewCPESet()
cpe1, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
cpe2, _ := cpe.ParseCpe23("cpe:2.3:a:apache:tomcat:9.0:*:*:*:*:*:*:*")
cpe3, _ := cpe.ParseCpe23("cpe:2.3:a:oracle:java:11:*:*:*:*:*:*:*")
set1.Add(cpe1, cpe2)
set2.Add(cpe2, cpe3) // cpe2 is in both sets
// Union operation
unionSet := set1.Union(set2)
fmt.Printf("Set1 size: %d\n", set1.Size())
fmt.Printf("Set2 size: %d\n", set2.Size())
fmt.Printf("Union size: %d\n", unionSet.Size()) // Should be 3 (unique items)Intersection
func (s *CPESet) Intersection(other *CPESet) *CPESetReturns a new set containing only CPEs that exist in both sets.
Parameters:
other- Another CPE set
Returns:
*CPESet- New set containing intersection of both sets
Example:
set1 := cpe.NewCPESet()
set2 := cpe.NewCPESet()
cpe1, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
cpe2, _ := cpe.ParseCpe23("cpe:2.3:a:apache:tomcat:9.0:*:*:*:*:*:*:*")
cpe3, _ := cpe.ParseCpe23("cpe:2.3:a:oracle:java:11:*:*:*:*:*:*:*")
set1.Add(cpe1, cpe2)
set2.Add(cpe2, cpe3)
// Intersection operation
intersectionSet := set1.Intersection(set2)
fmt.Printf("Intersection size: %d\n", intersectionSet.Size()) // Should be 1 (cpe2)Difference
func (s *CPESet) Difference(other *CPESet) *CPESetReturns a new set containing CPEs that are in this set but not in the other set.
Parameters:
other- Another CPE set
Returns:
*CPESet- New set containing difference
Example:
set1 := cpe.NewCPESet()
set2 := cpe.NewCPESet()
cpe1, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
cpe2, _ := cpe.ParseCpe23("cpe:2.3:a:apache:tomcat:9.0:*:*:*:*:*:*:*")
cpe3, _ := cpe.ParseCpe23("cpe:2.3:a:oracle:java:11:*:*:*:*:*:*:*")
set1.Add(cpe1, cpe2)
set2.Add(cpe2, cpe3)
// Difference operation
diffSet := set1.Difference(set2)
fmt.Printf("Difference size: %d\n", diffSet.Size()) // Should be 1 (cpe1)SymmetricDifference
func (s *CPESet) SymmetricDifference(other *CPESet) *CPESetReturns a new set containing CPEs that are in either set but not in both.
Parameters:
other- Another CPE set
Returns:
*CPESet- New set containing symmetric difference
Example:
set1 := cpe.NewCPESet()
set2 := cpe.NewCPESet()
cpe1, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
cpe2, _ := cpe.ParseCpe23("cpe:2.3:a:apache:tomcat:9.0:*:*:*:*:*:*:*")
cpe3, _ := cpe.ParseCpe23("cpe:2.3:a:oracle:java:11:*:*:*:*:*:*:*")
set1.Add(cpe1, cpe2)
set2.Add(cpe2, cpe3)
// Symmetric difference operation
symDiffSet := set1.SymmetricDifference(set2)
fmt.Printf("Symmetric difference size: %d\n", symDiffSet.Size()) // Should be 2 (cpe1, cpe3)Filtering Operations
Filter
func (s *CPESet) Filter(predicate func(*CPE) bool) *CPESetReturns a new set containing only CPEs that match the predicate function.
Parameters:
predicate- Function that returnstruefor CPEs to include
Returns:
*CPESet- New filtered set
Example:
set := cpe.NewCPESet()
cpe1, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
cpe2, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:office:2019:*:*:*:*:*:*:*")
cpe3, _ := cpe.ParseCpe23("cpe:2.3:a:apache:tomcat:9.0:*:*:*:*:*:*:*")
set.Add(cpe1, cpe2, cpe3)
// Filter for Microsoft products
microsoftSet := set.Filter(func(c *cpe.CPE) bool {
return string(c.Vendor) == "microsoft"
})
fmt.Printf("Microsoft products: %d\n", microsoftSet.Size()) // Should be 2FilterByVendor
func (s *CPESet) FilterByVendor(vendor string) *CPESetReturns a new set containing only CPEs from the specified vendor.
Parameters:
vendor- Vendor name to filter by
Returns:
*CPESet- New filtered set
FilterByProduct
func (s *CPESet) FilterByProduct(product string) *CPESetReturns a new set containing only CPEs for the specified product.
Parameters:
product- Product name to filter by
Returns:
*CPESet- New filtered set
FilterByPart
func (s *CPESet) FilterByPart(part *Part) *CPESetReturns a new set containing only CPEs of the specified part type.
Parameters:
part- Part type to filter by
Returns:
*CPESet- New filtered set
Example:
set := cpe.NewCPESet()
// ... add various CPEs ...
// Filter by different criteria
microsoftCPEs := set.FilterByVendor("microsoft")
windowsCPEs := set.FilterByProduct("windows")
applicationCPEs := set.FilterByPart(cpe.PartApplication)
fmt.Printf("Microsoft CPEs: %d\n", microsoftCPEs.Size())
fmt.Printf("Windows CPEs: %d\n", windowsCPEs.Size())
fmt.Printf("Application CPEs: %d\n", applicationCPEs.Size())Advanced Operations
AdvancedFilter
func (s *CPESet) AdvancedFilter(criteria *CPE, options *AdvancedMatchOptions) *CPESetFilters the set using advanced matching criteria.
Parameters:
criteria- CPE pattern to match againstoptions- Advanced matching options
Returns:
*CPESet- New filtered set
Example:
set := cpe.NewCPESet()
// ... populate set ...
// Create advanced matching criteria
criteria := &cpe.CPE{
Vendor: cpe.Vendor("microsoft"),
}
options := cpe.NewAdvancedMatchOptions()
options.MatchMode = "distance"
options.ScoreThreshold = 0.8
// Advanced filter
filteredSet := set.AdvancedFilter(criteria, options)
fmt.Printf("Advanced filtered set size: %d\n", filteredSet.Size())FindRelated
func FindRelated(cpe *CPE, set *CPESet, options *MatchOptions) *CPESetFinds CPEs in the set that are related to the given CPE.
Parameters:
cpe- CPE to find related items forset- Set to search inoptions- Matching options
Returns:
*CPESet- Set of related CPEs
Example:
targetCPE, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:*:*:*:*:*:*:*:*")
relatedSet := cpe.FindRelated(targetCPE, set, cpe.DefaultMatchOptions())
fmt.Printf("Found %d related CPEs\n", relatedSet.Size())Conversion Operations
ToArray
func (s *CPESet) ToArray() []*CPEConverts the set to an array of CPE objects.
Returns:
[]*CPE- Array containing all CPEs in the set
ToStrings
func (s *CPESet) ToStrings() []stringConverts the set to an array of CPE strings.
Returns:
[]string- Array of CPE string representations
Example:
set := cpe.NewCPESet()
// ... populate set ...
// Convert to array
cpeArray := set.ToArray()
fmt.Printf("Array length: %d\n", len(cpeArray))
// Convert to strings
cpeStrings := set.ToStrings()
for i, cpeStr := range cpeStrings {
fmt.Printf("%d: %s\n", i+1, cpeStr)
}Complete Example
package main
import (
"fmt"
"log"
"github.com/scagogogo/cpe"
)
func main() {
// Create CPE objects
cpe1, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
cpe2, _ := cpe.ParseCpe23("cpe:2.3:a:microsoft:office:2019:*:*:*:*:*:*:*")
cpe3, _ := cpe.ParseCpe23("cpe:2.3:a:apache:tomcat:9.0:*:*:*:*:*:*:*")
cpe4, _ := cpe.ParseCpe23("cpe:2.3:a:oracle:java:11:*:*:*:*:*:*:*")
// Create sets
fmt.Println("=== Creating Sets ===")
set1 := cpe.NewCPESet()
set1.Add(cpe1, cpe2, cpe3)
set2 := cpe.NewCPESet()
set2.Add(cpe3, cpe4)
fmt.Printf("Set1 size: %d\n", set1.Size())
fmt.Printf("Set2 size: %d\n", set2.Size())
// Set operations
fmt.Println("\n=== Set Operations ===")
unionSet := set1.Union(set2)
intersectionSet := set1.Intersection(set2)
differenceSet := set1.Difference(set2)
fmt.Printf("Union size: %d\n", unionSet.Size())
fmt.Printf("Intersection size: %d\n", intersectionSet.Size())
fmt.Printf("Difference size: %d\n", differenceSet.Size())
// Filtering
fmt.Println("\n=== Filtering ===")
microsoftSet := set1.FilterByVendor("microsoft")
fmt.Printf("Microsoft products: %d\n", microsoftSet.Size())
// Custom filter
applicationSet := set1.Filter(func(c *cpe.CPE) bool {
return c.Part.ShortName == "a"
})
fmt.Printf("Applications: %d\n", applicationSet.Size())
// Advanced filtering
fmt.Println("\n=== Advanced Filtering ===")
criteria := &cpe.CPE{
Vendor: cpe.Vendor("microsoft"),
}
options := cpe.NewAdvancedMatchOptions()
options.MatchMode = "exact"
advancedFiltered := set1.AdvancedFilter(criteria, options)
fmt.Printf("Advanced filtered: %d\n", advancedFiltered.Size())
// Convert to arrays
fmt.Println("\n=== Conversion ===")
cpeArray := microsoftSet.ToArray()
cpeStrings := microsoftSet.ToStrings()
fmt.Printf("Microsoft products:\n")
for i, cpeStr := range cpeStrings {
fmt.Printf("%d. %s\n", i+1, cpeStr)
}
// Set membership tests
fmt.Println("\n=== Membership Tests ===")
fmt.Printf("Set1 contains Windows: %t\n", set1.Contains(cpe1))
fmt.Printf("Set1 contains Java: %t\n", set1.Contains(cpe4))
// Create set from strings
fmt.Println("\n=== Creating from Strings ===")
cpeStrings2 := []string{
"cpe:2.3:a:google:chrome:95.0:*:*:*:*:*:*:*",
"cpe:2.3:a:mozilla:firefox:94.0:*:*:*:*:*:*:*",
}
browserSet, err := cpe.FromStrings(cpeStrings2)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Browser set size: %d\n", browserSet.Size())
}