Parsing
The CPE library provides comprehensive parsing capabilities for both CPE 2.2 and CPE 2.3 formats, converting string representations into structured CPE objects.
The diagram below illustrates how parsing and formatting are inverse operations, and how a CPE 2.2 string is converted to CPE 2.3 by parsing it and re-formatting the result:
CPE 2.3 Parsing
ParseCpe23
func ParseCpe23(cpe23 string) (*CPE, error)Parses a CPE 2.3 format string and converts it to a CPE structure.
Parameters:
cpe23- CPE 2.3 format string (e.g.,"cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
Returns:
*CPE- Parsed CPE objecterror- Error if parsing fails
Errors:
- An invalid-format error when the string does not have exactly 13 colon-separated parts or does not begin with
cpe:2.3:(detectable withIsInvalidFormatError) - An invalid-part error when the part field value is not
a,h,o, or*(detectable withIsInvalidPartError)
Example:
// Parse Windows 10 CPE
winCPE, err := cpeskills.ParseCpe23("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
if err != nil {
log.Fatalf("Failed to parse CPE: %v", err)
}
fmt.Printf("Vendor: %s\n", winCPE.Vendor) // microsoft
fmt.Printf("Product: %s\n", winCPE.ProductName) // windows
fmt.Printf("Version: %s\n", winCPE.Version) // 10
// Parse Adobe Reader CPE
adobeCPE, err := cpeskills.ParseCpe23("cpe:2.3:a:adobe:reader:2021.001.20150:*:*:*:*:*:*:*")
if err != nil {
log.Fatalf("Failed to parse CPE: %v", err)
}
// Parse operating system CPE
osCPE, err := cpeskills.ParseCpe23("cpe:2.3:o:microsoft:windows:10:1909:*:*:*:*:*:*")
if err != nil {
log.Fatalf("Failed to parse CPE: %v", err)
}CPE 2.3 Format Structure
The CPE 2.3 format follows this structure:
cpe:2.3:<part>:<vendor>:<product>:<version>:<update>:<edition>:<language>:<sw_edition>:<target_sw>:<target_hw>:<other>Fields:
part- Component type: "a" (application), "h" (hardware), "o" (operating system)vendor- Vendor/manufacturer nameproduct- Product nameversion- Product versionupdate- Update identifieredition- Edition identifierlanguage- Language codesw_edition- Software editiontarget_sw- Target softwaretarget_hw- Target hardwareother- Other attributes
Special Values:
*- Wildcard (matches any value)-- Not applicable
CPE 2.2 Parsing
ParseCpe22
func ParseCpe22(cpe22 string) (*CPE, error)Parses a CPE 2.2 format string and converts it to a CPE structure.
Parameters:
cpe22- CPE 2.2 format string (e.g.,"cpe:/a:apache:tomcat:8.5.0")
Returns:
*CPE- Parsed CPE objecterror- Error if parsing fails
Errors:
- An invalid-format error when the string does not start with
cpe:/(detectable withIsInvalidFormatError) - An invalid-part error when the part field value is not
a,h, oro(detectable withIsInvalidPartError)
Example:
// Parse basic CPE 2.2 format
tomcatCPE, err := cpeskills.ParseCpe22("cpe:/a:apache:tomcat:8.5.0")
if err != nil {
log.Fatalf("Failed to parse CPE: %v", err)
}
fmt.Printf("Part: %s\n", tomcatCPE.Part.LongName) // Application
fmt.Printf("Vendor: %s\n", tomcatCPE.Vendor) // apache
fmt.Printf("Product: %s\n", tomcatCPE.ProductName) // tomcat
fmt.Printf("Version: %s\n", tomcatCPE.Version) // 8.5.0
// Parse a CPE 2.2 string with an extended (~-separated) field section
mysqlCPE, err := cpeskills.ParseCpe22("cpe:/a:mysql:mysql:5.7.12:::~~~enterprise~")
if err != nil {
log.Fatalf("Failed to parse CPE: %v", err)
}
fmt.Printf("Software edition: %s\n", mysqlCPE.SoftwareEdition) // enterpriseCPE 2.2 Format Structure
The CPE 2.2 format follows this structure:
cpe:/<part>:<vendor>:<product>:<version>:<update>:<edition>:<language>Extended format with additional fields:
cpe:/<part>:<vendor>:<product>:<version>:<update>:<edition>:<language>:~<sw_edition>~<target_sw>~<target_hw>~<other>Format Conversion
FormatCpe23
func FormatCpe23(cpe *CPE) stringConverts a CPE object to a CPE 2.3 format string. If the object already carries a Cpe23 value it is returned as-is; otherwise a new string is built from the fields, with empty fields replaced by the wildcard *.
Parameters:
cpe- CPE object to format
Returns:
string- CPE 2.3 format string
Example:
cpeObj := &cpeskills.CPE{
Part: *cpeskills.PartApplication,
Vendor: cpeskills.Vendor("microsoft"),
ProductName: cpeskills.Product("windows"),
Version: cpeskills.Version("10"),
}
cpe23String := cpeskills.FormatCpe23(cpeObj)
fmt.Println(cpe23String) // cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*FormatCpe22
func FormatCpe22(cpe *CPE) stringConverts a CPE object to a CPE 2.2 format string.
Parameters:
cpe- CPE object to format
Returns:
string- CPE 2.2 format string
Example:
cpeObj := &cpeskills.CPE{
Part: *cpeskills.PartApplication,
Vendor: cpeskills.Vendor("apache"),
ProductName: cpeskills.Product("tomcat"),
Version: cpeskills.Version("8.5.0"),
}
cpe22String := cpeskills.FormatCpe22(cpeObj)
fmt.Println(cpe22String) // cpe:/a:apache:tomcat:8.5.0FormatCPE
func FormatCPE(cpe *CPE, version string) (string, error)Formats a CPE object as either a 2.2 or 2.3 string, selected by the version argument. Accepts "2.3", "23" or "" for CPE 2.3, and "2.2" or "22" for CPE 2.2. Any other value returns an error.
Parameters:
cpe- CPE object to formatversion- Target version selector
Returns:
string- Formatted CPE stringerror- Error ifcpeisnilorversionis unsupported
Example:
cpeObj := &cpeskills.CPE{
Part: *cpeskills.PartApplication,
Vendor: cpeskills.Vendor("apache"),
ProductName: cpeskills.Product("tomcat"),
Version: cpeskills.Version("8.5.0"),
}
str, err := cpeskills.FormatCPE(cpeObj, "2.2")
if err != nil {
log.Fatal(err)
}
fmt.Println(str) // cpe:/a:apache:tomcat:8.5.0Conversion Between Formats
To convert a CPE 2.2 string to CPE 2.3, parse it with ParseCpe22 and re-format the resulting object with FormatCpe23. (In fact, ParseCpe22 already populates the object's Cpe23 field, so FormatCpe23 simply returns it.)
Example:
cpe22 := "cpe:/a:apache:tomcat:8.5.0"
cpeObj, err := cpeskills.ParseCpe22(cpe22)
if err != nil {
log.Fatal(err)
}
cpe23 := cpeskills.FormatCpe23(cpeObj)
fmt.Println(cpe23) // cpe:2.3:a:apache:tomcat:8.5.0:*:*:*:*:*:*:*Convenience Parsing
Parse
func Parse(cpeStr string) (*CPE, error)Parses a CPE string, automatically detecting whether it is in CPE 2.2 or CPE 2.3 form.
MustParse
func MustParse(cpeStr string) *CPELike Parse, but panics instead of returning an error. Handy for package-level variable initialization with known-good literals.
Example:
// Auto-detect the format
cpeObj, err := cpeskills.Parse("cpe:/a:apache:tomcat:8.5.0")
if err != nil {
log.Fatal(err)
}
fmt.Println(cpeObj.Vendor) // apache
// Panics on invalid input; use only with trusted literals
var windows = cpeskills.MustParse("cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*")
fmt.Println(windows.ProductName) // windowsError Handling
// Handle parsing errors
cpeObj, err := cpeskills.ParseCpe23("invalid:format")
if err != nil {
if cpeskills.IsInvalidFormatError(err) {
fmt.Println("Invalid CPE format")
} else if cpeskills.IsInvalidPartError(err) {
fmt.Println("Invalid part value")
} else {
fmt.Printf("Other error: %v\n", err)
}
}Best Practices
- Always check for errors when parsing CPE strings
- Use the appropriate parser for the format you're working with, or
Parseto auto-detect - Validate input before parsing if the source is untrusted
- Handle special characters properly when constructing CPE strings manually
- Use format conversion functions when you need to switch between formats
Complete Example
package main
import (
"fmt"
"log"
"github.com/scagogogo/cpe-skills"
)
func main() {
// Parse different CPE formats
examples := []string{
"cpe:2.3:a:microsoft:windows:10:*:*:*:*:*:*:*",
"cpe:2.3:a:adobe:reader:2021.001.20150:*:*:*:*:*:*:*",
"cpe:2.3:o:linux:kernel:5.4.0:*:*:*:*:*:*:*",
}
for _, example := range examples {
cpeObj, err := cpeskills.ParseCpe23(example)
if err != nil {
log.Printf("Failed to parse %s: %v", example, err)
continue
}
fmt.Printf("Parsed: %s\n", example)
fmt.Printf(" Type: %s\n", cpeObj.Part.LongName)
fmt.Printf(" Vendor: %s\n", cpeObj.Vendor)
fmt.Printf(" Product: %s\n", cpeObj.ProductName)
fmt.Printf(" Version: %s\n", cpeObj.Version)
fmt.Println()
}
// Parse CPE 2.2 format
cpe22Example := "cpe:/a:apache:tomcat:8.5.0"
cpe22Obj, err := cpeskills.ParseCpe22(cpe22Example)
if err != nil {
log.Fatal(err)
}
// Convert to CPE 2.3
cpe23String := cpeskills.FormatCpe23(cpe22Obj)
fmt.Printf("CPE 2.2: %s\n", cpe22Example)
fmt.Printf("CPE 2.3: %s\n", cpe23String)
}