blob: 0b84237332f3760c2c281dcfd7f0979384d0c89c [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 client
import (
"encoding/json"
"path"
"sort"
"time"
)
const (
idDir = "ID"
indexDir = "index"
)
var (
dbEndpoint = path.Join(indexDir, "db")
modulesEndpoint = path.Join(indexDir, "modules")
)
func entryEndpoint(id string) string {
return path.Join(idDir, id)
}
// dbMeta contains metadata about the database itself.
type dbMeta struct {
// Modified is the time the database was last modified, calculated
// as the most recent time any single OSV entry was modified.
Modified time.Time `json:"modified"`
}
// moduleMeta contains metadata about a Go module that has one
// or more vulnerabilities in the database.
//
// Found in the "index/modules" endpoint of the vulnerability database.
type moduleMeta struct {
// Path is the module path.
Path string `json:"path"`
// Vulns is a list of vulnerabilities that affect this module.
Vulns []moduleVuln `json:"vulns"`
}
// moduleVuln contains metadata about a vulnerability that affects
// a certain module.
type moduleVuln struct {
// ID is a unique identifier for the vulnerability.
// The Go vulnerability database issues IDs of the form
// GO-<YEAR>-<ENTRYID>.
ID string `json:"id"`
// Modified is the time the vuln was last modified.
Modified time.Time `json:"modified"`
// Fixed is the latest version that introduces a fix for the
// vulnerability, in SemVer 2.0.0 format, with no leading "v" prefix.
Fixed string `json:"fixed,omitempty"`
}
// modulesIndex represents an in-memory modules index.
type modulesIndex map[string]*moduleMeta
func (m modulesIndex) MarshalJSON() ([]byte, error) {
modules := make([]*moduleMeta, 0, len(m))
for _, module := range m {
modules = append(modules, module)
}
sort.SliceStable(modules, func(i, j int) bool {
return modules[i].Path < modules[j].Path
})
for _, module := range modules {
sort.SliceStable(module.Vulns, func(i, j int) bool {
return module.Vulns[i].ID < module.Vulns[j].ID
})
}
return json.Marshal(modules)
}