schema.go (2138B)
1 // Copyright 2023 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package client 6 7 import ( 8 "encoding/json" 9 "path" 10 "sort" 11 "time" 12 ) 13 14 const ( 15 idDir = "ID" 16 indexDir = "index" 17 ) 18 19 var ( 20 dbEndpoint = path.Join(indexDir, "db") 21 modulesEndpoint = path.Join(indexDir, "modules") 22 ) 23 24 func entryEndpoint(id string) string { 25 return path.Join(idDir, id) 26 } 27 28 // dbMeta contains metadata about the database itself. 29 type dbMeta struct { 30 // Modified is the time the database was last modified, calculated 31 // as the most recent time any single OSV entry was modified. 32 Modified time.Time `json:"modified"` 33 } 34 35 // moduleMeta contains metadata about a Go module that has one 36 // or more vulnerabilities in the database. 37 // 38 // Found in the "index/modules" endpoint of the vulnerability database. 39 type moduleMeta struct { 40 // Path is the module path. 41 Path string `json:"path"` 42 // Vulns is a list of vulnerabilities that affect this module. 43 Vulns []moduleVuln `json:"vulns"` 44 } 45 46 // moduleVuln contains metadata about a vulnerability that affects 47 // a certain module. 48 type moduleVuln struct { 49 // ID is a unique identifier for the vulnerability. 50 // The Go vulnerability database issues IDs of the form 51 // GO-<YEAR>-<ENTRYID>. 52 ID string `json:"id"` 53 // Modified is the time the vuln was last modified. 54 Modified time.Time `json:"modified"` 55 // Fixed is the latest version that introduces a fix for the 56 // vulnerability, in SemVer 2.0.0 format, with no leading "v" prefix. 57 Fixed string `json:"fixed,omitempty"` 58 } 59 60 // modulesIndex represents an in-memory modules index. 61 type modulesIndex map[string]*moduleMeta 62 63 func (m modulesIndex) MarshalJSON() ([]byte, error) { 64 modules := make([]*moduleMeta, 0, len(m)) 65 for _, module := range m { 66 modules = append(modules, module) 67 } 68 sort.SliceStable(modules, func(i, j int) bool { 69 return modules[i].Path < modules[j].Path 70 }) 71 for _, module := range modules { 72 sort.SliceStable(module.Vulns, func(i, j int) bool { 73 return module.Vulns[i].ID < module.Vulns[j].ID 74 }) 75 } 76 return json.Marshal(modules) 77 }