// 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--. 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) }