Skip to content

📚 CPE 字典

dictionary 模块建模 NVD CPE 字典:CPEDictionary 持有 CPEItem 条目列表,每个条目封装一个 CPE 及人类可读的元数据(标题、参考链接、弃用状态)。该模块解析官方 NVD XML 字典并重新导出,同时提供内存查询与变更辅助方法。

类型:CPEDictionary

go
type CPEDictionary struct {
    Items         []*CPEItem `json:"items" bson:"items"`           // CPE 条目列表
    GeneratedAt   time.Time  `json:"generated_at" bson:"generated_at"` // 字典生成时间
    SchemaVersion string     `json:"schema_version" bson:"schema_version"` // CPE 规范版本
}

CPEDictionary 是顶层容器。Items 为权威列表;GeneratedAtSchemaVersion 携带来自源 XML 的来源信息。

类型:CPEItem

go
type CPEItem struct {
    Name            string     `json:"name" xml:"name" bson:"name"`                 // 标准 CPE 名称(2.3 形式)
    Title           string     `json:"title" xml:"title" bson:"title"`              // 人类可读标题
    References      []Reference `json:"references" xml:"references>reference" bson:"references"` // 参考链接
    Deprecated      bool       `json:"deprecated" xml:"deprecated,attr" bson:"deprecated"` // 是否已弃用
    DeprecationDate *time.Time `json:"deprecation_date" xml:"deprecation_date" bson:"deprecation_date"` // 弃用日期
    CPE             *CPE       `json:"cpe" bson:"cpe"`                               // 解析后的 CPE 对象
}

CPEItem 表示单个字典条目。CPEName 的解析形式(由 ParseDictionary 填充);若名称无法解析则为 nil

类型:Reference

go
type Reference struct {
    URL  string `json:"url" xml:"href,attr" bson:"url"`  // 参考 URL
    Type string `json:"type" xml:"type" bson:"type"`     // 引用类型,如 "Vendor"、"Advisory"
}

Reference 是附加到 CPEItem 的单个外部链接。

📖 ParseDictionary

go
func ParseDictionary(r io.Reader) (*CPEDictionary, error)

r 解码 NVD CPE 字典 XML 流,将每个 <cpe-item> 转换为 CPEItem。每项的 Name 被解析(2.3 或 2.2)为 CPEDeprecated/DeprecationDateReferences 从 XML 属性/子元素填充。GeneratedAt 在存在时按 RFC3339 解析。失败时返回包装 XML 解码错误的 OperationFailedError

参数类型说明
rio.ReaderXML 数据流
返回值类型说明
#1*CPEDictionary解析得到的字典
#2errorXML 解码失败时非 nil(已包装)
go
file, _ := os.Open("official-cpe-dictionary_v2.3.xml")
defer file.Close()
dict, err := cpeskills.ParseDictionary(file)
if err != nil {
    log.Fatalf("parse: %v", err)
}
fmt.Printf("%d items\n", len(dict.Items))

📤 ExportDictionary

go
func ExportDictionary(dict *CPEDictionary, w io.Writer) error

dict 序列化为 NVD CPE 字典 XML,向 w 写入 XML 头部和缩进的 <cpe-list>。失败时返回包装底层 I/O 或编码错误的 OperationFailedError

参数类型说明
dict*CPEDictionary要导出的字典
wio.WriterXML 输出目标
返回值类型说明
#1error写入/编码失败时非 nil(已包装)
go
var buf bytes.Buffer
if err := cpeskills.ExportDictionary(dict, &buf); err != nil {
    log.Fatalf("export: %v", err)
}

🔍 FindItemByName

go
func (d *CPEDictionary) FindItemByName(name string) *CPEItem

返回第一个 Name 等于 name 的条目,无则返回 nil

参数类型说明
接收者*CPEDictionary字典
namestring要查找的 CPE 名称(2.3 形式)
返回值类型说明
#1*CPEItem匹配的条目,或 nil
go
item := dict.FindItemByName("cpe:2.3:a:apache:log4j:2.0:*:*:*:*:*:*:*")

🔍 FindItemsByCriteria

go
func (d *CPEDictionary) FindItemsByCriteria(criteria *CPE, options *MatchOptions) []*CPEItem

返回所有已解析 CPEoptions 下匹配 criteria 的条目(通过包内部 matchCPE)。CPEnil 的条目被跳过。

参数类型说明
接收者*CPEDictionary字典
criteria*CPE匹配条件
options*MatchOptions匹配选项
返回值类型说明
#1[]*CPEItem匹配的条目(无则空/nil
go
items := dict.FindItemsByCriteria(&cpeskills.CPE{
    Vendor: cpeskills.Vendor("apache"),
}, &cpeskills.MatchOptions{IgnoreVersion: true})

➕ AddItem

go
func (d *CPEDictionary) AddItem(item *CPEItem)

item 加入字典。若已存在同名条目,则就地替换;否则追加。

参数类型说明
接收者*CPEDictionary字典
item*CPEItem要添加的条目
返回值类型说明
(无)
go
dict.AddItem(cpeskills.NewCPEItem(cpe, "Apache Log4j 2.0"))

➖ RemoveItem

go
func (d *CPEDictionary) RemoveItem(name string) bool

移除 Name 等于 name 的条目。移除了返回 true,否则返回 false

参数类型说明
接收者*CPEDictionary字典
namestring要移除的 CPE 名称
返回值类型说明
#1bool移除成功为 true
go
if dict.RemoveItem("cpe:2.3:a:apache:log4j:2.0:*:*:*:*:*:*:*") {
    fmt.Println("removed")
}

🆕 NewCPEItem

go
func NewCPEItem(cpe *CPE, title string) *CPEItem

cpetitle 创建 CPEItemcpe.Cpe23 非空时 Name 设为它,否则设为 FormatCpe23(cpe)CPE 设为 cpe

参数类型说明
cpe*CPECPE
titlestring人类可读标题
返回值类型说明
#1*CPEItem新的字典条目
go
item := cpeskills.NewCPEItem(cpe, "Apache Log4j 2.0")
dict.AddItem(item)

🧭 Dictionary 解析与查询流

Released under the MIT License.