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() *CPESet
Creates 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) *CPESet
Creates 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) *CPESet
Adds 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) bool
Removes a CPE object from the set.
Parameters:
cpe
- CPE object to remove
Returns:
bool
-true
if the CPE was removed,false
if 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) bool
Checks if the set contains a specific CPE object.
Parameters:
cpe
- CPE object to check for
Returns:
bool
-true
if the set contains the CPE,false
otherwise
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() int
Returns the number of CPE objects in the set.
Returns:
int
- Number of items in the set
IsEmpty
func (s *CPESet) IsEmpty() bool
Checks if the set is empty.
Returns:
bool
-true
if the set is empty,false
otherwise
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) *CPESet
Returns 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) *CPESet
Returns 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) *CPESet
Returns 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) *CPESet
Returns 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) *CPESet
Returns a new set containing only CPEs that match the predicate function.
Parameters:
predicate
- Function that returnstrue
for 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 2
FilterByVendor
func (s *CPESet) FilterByVendor(vendor string) *CPESet
Returns 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) *CPESet
Returns 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) *CPESet
Returns 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) *CPESet
Filters 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) *CPESet
Finds 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() []*CPE
Converts the set to an array of CPE objects.
Returns:
[]*CPE
- Array containing all CPEs in the set
ToStrings
func (s *CPESet) ToStrings() []string
Converts 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())
}