Skip to content

Go SDK

Go SDK 是 CLI 和技能之下的类型安全基石。当你要把 OSV 解析/过滤/查询嵌入 Go 应用时用它。

安装

bash
go get -u github.com/scagogogo/osv-schema-skills
go
import osv "github.com/scagogogo/osv-schema-skills"

快速开始

go
package main

import (
    "fmt"
    "log"

    osv "github.com/scagogogo/osv-schema-skills"
)

func main() {
    // 从 JSON 文件解析 OSV 数据
    v, err := osv.UnmarshalFromJsonFile[any, any]("vulnerability.json")
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("ID: %s\n", v.ID)
    fmt.Printf("Summary: %s\n", v.Summary)

    // 从 aliases 取 CVE
    if cve := v.Aliases.GetCVE(); cve != "" {
        fmt.Printf("CVE: %s\n", cve)
    }

    // 检查是否影响某生态
    if v.Affected.HasEcosystem(osv.EcosystemPyPI) {
        fmt.Println("影响 PyPI 包")
    }

    // 取 CVSS v3 分数
    if cvss3 := v.Severity.GetCVSS3(); cvss3 != nil {
        fmt.Printf("CVSS v3: %.1f\n", cvss3.GetScore())
    }
}

从 JSON 到代码:对象生命周期

核心类型

go
type OsvSchema[EcosystemSpecific, DatabaseSpecific any] struct {
    SchemaVersion    string
    ID               string
    Modified         time.Time
    Published        time.Time
    Withdrawn        string // string,不是 time.Time——非空即表示已撤回
    Aliases          Aliases
    Related          Related
    Summary          string
    Details          string
    Severity         SeveritySlice
    Affected         AffectedSlice[EcosystemSpecific, DatabaseSpecific]
    References       References
    DatabaseSpecific DatabaseSpecific
    Credits          *Credits
}

泛型参数 EcosystemSpecificDatabaseSpecific 让你按生态或漏洞库附加自定义数据。通用解析用 any

类型关系一图

关键方法

完整表见 参考 → 方法清单。要点:

类型方法说明
OsvSchemaAffected.HasEcosystem(eco)检查是否影响某生态
AffectedSliceFilterByEcosystem(eco)过滤受影响包
AliasesGetCVE()取第一个 CVE 标识
SeveritySliceGetCVSS3() / GetCVSS2()取 CVSS severity 条目
SeverityGetScore()解析分数为 float64
ReferencesFilterByType(t)按引用类型过滤
PackageIsMaven() / GetGroupID() / GetArtifactID()Maven 拆分

序列化

每个核心类型都带 jsonyamlmapstructuredbbsongorm 标签——JSON、YAML、mapstructure、GORM 和 MongoDB(BSON)开箱即用。

带类型的厂商字段——实战示例

[any, any] 适合大多数解析,但当你反复读取一个已知形态的 database_specific(比如 GitHub 的公告块)时,给它一个具体类型,编译器就会替你检查字段访问。

go
// 定义你关心的厂商块形态
type GHSA struct {
    Severity         string   `json:"severity"`
    CWEIDs           []string `json:"cwe_ids"`
    GitHubReviewedAt string   `json:"github_reviewed_at"`
}

// 用具体类型作为 DatabaseSpecific 解析
v, err := osv.UnmarshalFromJsonFile[any, GHSA]("ghsa.json")
if err != nil {
    log.Fatal(err)
}
// v.DatabaseSpecific 现在是带类型的 GHSA——无需 map[string]any 强转
fmt.Println(v.DatabaseSpecific.Severity, v.DatabaseSpecific.CWEIDs)

只为需要的类型付费

两个参数相互独立。只给 DatabaseSpecific 定类型、EcosystemSpecificany(反之亦然)——不必两个块都建模才能给其中一个上类型。

设计要点

  • 成功时永不 nil,出错时必为 nil——UnmarshalFromJsonFile / UnmarshalFromJson 失败时返回 (nil, err),成功时返回非 nil 的 *OsvSchema。碰指针前先检查 err
  • Withdrawn 是字符串——不是 time.Time。用非空字符串判断撤回状态。
  • SDK 结构体不带 omitempty——OsvSchema / Event / Package 结构体有序列化标签但无 omitempty。故对一条半填充记录 json.Marshal(v) 会输出空字段("withdrawn": """published":"0001-01-01T00:00:00Z""fixed": "")。CLI 的 -o json 通过自带带 omitempty 的 DTO 层规避了这点;若你在 SDK 里也想要同样干净的输出,请自建 DTO 或自行过滤空字段。
  • 数据库策略——简单字段做列;复杂嵌套结构(AffectedSliceSeveritySlice)经 GORM serializer 存为 JSON 字符串。

环境要求

  • Go 1.18+

Last updated:

Released under the MIT License.