blob: dc76a6ae967eabc1f373211d4b3b161fd7575c4f [file] [log] [blame]
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package genericosv
import (
"fmt"
"strings"
osvschema "github.com/google/osv-scanner/pkg/models"
"golang.org/x/vulndb/internal/cveschema5"
"golang.org/x/vulndb/internal/ghsa"
"golang.org/x/vulndb/internal/osv"
"golang.org/x/vulndb/internal/report"
)
var _ report.Source = &Entry{}
// ToReport converts OSV into a Go Report with the given ID.
func (osv *Entry) ToReport(string) *report.Report {
r := &report.Report{
Summary: report.Summary(osv.Summary),
Description: report.Description(osv.Details),
}
addAlias := func(alias string) {
switch {
case cveschema5.IsCVE(alias):
r.CVEs = append(r.CVEs, alias)
case ghsa.IsGHSA(alias):
r.GHSAs = append(r.GHSAs, alias)
default:
r.UnknownAliases = append(r.UnknownAliases, alias)
}
}
addAlias(osv.ID)
for _, alias := range osv.Aliases {
addAlias(alias)
}
r.Modules = affectedToModules(osv.Affected)
for _, ref := range osv.References {
r.References = append(r.References, convertRef(ref))
}
r.Credits = convertCredits(osv.Credits)
return r
}
func (osv *Entry) SourceID() string {
return osv.ID
}
func affectedToModules(as []osvschema.Affected) []*report.Module {
var modules []*report.Module
for _, a := range as {
if a.Package.Ecosystem != osvschema.EcosystemGo {
continue
}
versions, unsupportedVersions := convertVersions(a.Ranges)
modules = append(modules, &report.Module{
Module: a.Package.Name,
Versions: versions,
UnsupportedVersions: unsupportedVersions,
})
}
return modules
}
func convertVersions(rs []osvschema.Range) ([]report.VersionRange, []report.UnsupportedVersion) {
var vrs []report.VersionRange
var uvs []report.UnsupportedVersion
for _, r := range rs {
for _, e := range r.Events {
if e.Introduced != "" || e.Fixed != "" {
var vr report.VersionRange
switch {
case e.Introduced == "0":
continue
case e.Introduced != "":
vr.Introduced = e.Introduced
case e.Fixed != "":
vr.Fixed = e.Fixed
}
vrs = append(vrs, vr)
continue
}
var uv report.UnsupportedVersion
switch {
case e.LastAffected != "":
uv.Version = e.LastAffected
uv.Type = "last_affected"
case e.Limit != "":
uv.Version = e.Limit
uv.Type = "limit"
default:
uv.Version = fmt.Sprint(e)
uv.Type = "unknown"
}
uvs = append(uvs, uv)
}
}
return vrs, uvs
}
func convertRef(ref osvschema.Reference) *report.Reference {
return &report.Reference{
Type: osv.ReferenceType(ref.Type),
URL: ref.URL,
}
}
func convertCredits(cs []osvschema.Credit) []string {
var credits []string
for _, c := range cs {
credit := c.Name
if len(c.Contact) != 0 {
credit = fmt.Sprintf("%s (%s)", c.Name, strings.Join(c.Contact, ","))
}
credits = append(credits, credit)
}
return credits
}