Initialize module and dependencies
This commit is contained in:
290
vendor/golang.org/x/vuln/internal/scan/template.go
generated
vendored
Normal file
290
vendor/golang.org/x/vuln/internal/scan/template.go
generated
vendored
Normal file
@@ -0,0 +1,290 @@
|
||||
// Copyright 2022 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 scan
|
||||
|
||||
import (
|
||||
"go/token"
|
||||
"io"
|
||||
"path"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"golang.org/x/vuln/internal/govulncheck"
|
||||
"golang.org/x/vuln/internal/osv"
|
||||
"golang.org/x/vuln/internal/traces"
|
||||
)
|
||||
|
||||
type findingSummary struct {
|
||||
*govulncheck.Finding
|
||||
Compact string
|
||||
OSV *osv.Entry
|
||||
}
|
||||
|
||||
type summaryCounters struct {
|
||||
VulnerabilitiesCalled int
|
||||
ModulesCalled int
|
||||
VulnerabilitiesImported int
|
||||
VulnerabilitiesRequired int
|
||||
StdlibCalled bool
|
||||
}
|
||||
|
||||
func fixupFindings(osvs []*osv.Entry, findings []*findingSummary) {
|
||||
for _, f := range findings {
|
||||
f.OSV = getOSV(osvs, f.Finding.OSV)
|
||||
}
|
||||
}
|
||||
|
||||
func groupByVuln(findings []*findingSummary) [][]*findingSummary {
|
||||
return groupBy(findings, func(left, right *findingSummary) int {
|
||||
return -strings.Compare(left.OSV.ID, right.OSV.ID)
|
||||
})
|
||||
}
|
||||
|
||||
func groupByModule(findings []*findingSummary) [][]*findingSummary {
|
||||
return groupBy(findings, func(left, right *findingSummary) int {
|
||||
return strings.Compare(left.Trace[0].Module, right.Trace[0].Module)
|
||||
})
|
||||
}
|
||||
|
||||
func groupBy(findings []*findingSummary, compare func(left, right *findingSummary) int) [][]*findingSummary {
|
||||
switch len(findings) {
|
||||
case 0:
|
||||
return nil
|
||||
case 1:
|
||||
return [][]*findingSummary{findings}
|
||||
}
|
||||
sort.SliceStable(findings, func(i, j int) bool {
|
||||
return compare(findings[i], findings[j]) < 0
|
||||
})
|
||||
result := [][]*findingSummary{}
|
||||
first := 0
|
||||
for i, next := range findings {
|
||||
if i == first {
|
||||
continue
|
||||
}
|
||||
if compare(findings[first], next) != 0 {
|
||||
result = append(result, findings[first:i])
|
||||
first = i
|
||||
}
|
||||
}
|
||||
result = append(result, findings[first:])
|
||||
return result
|
||||
}
|
||||
|
||||
func isRequired(findings []*findingSummary) bool {
|
||||
for _, f := range findings {
|
||||
if f.Trace[0].Module != "" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isImported(findings []*findingSummary) bool {
|
||||
for _, f := range findings {
|
||||
if f.Trace[0].Package != "" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isCalled(findings []*findingSummary) bool {
|
||||
for _, f := range findings {
|
||||
if f.Trace[0].Function != "" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func getOSV(osvs []*osv.Entry, id string) *osv.Entry {
|
||||
for _, entry := range osvs {
|
||||
if entry.ID == id {
|
||||
return entry
|
||||
}
|
||||
}
|
||||
return &osv.Entry{
|
||||
ID: id,
|
||||
DatabaseSpecific: &osv.DatabaseSpecific{},
|
||||
}
|
||||
}
|
||||
|
||||
func newFindingSummary(f *govulncheck.Finding) *findingSummary {
|
||||
return &findingSummary{
|
||||
Finding: f,
|
||||
Compact: compactTrace(f),
|
||||
}
|
||||
}
|
||||
|
||||
// platforms returns a string describing the GOOS, GOARCH,
|
||||
// or GOOS/GOARCH pairs that the vuln affects for a particular
|
||||
// module mod. If it affects all of them, it returns the empty
|
||||
// string.
|
||||
//
|
||||
// When mod is an empty string, returns platform information for
|
||||
// all modules of e.
|
||||
func platforms(mod string, e *osv.Entry) []string {
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
platforms := map[string]bool{}
|
||||
for _, a := range e.Affected {
|
||||
if mod != "" && a.Module.Path != mod {
|
||||
continue
|
||||
}
|
||||
for _, p := range a.EcosystemSpecific.Packages {
|
||||
for _, os := range p.GOOS {
|
||||
// In case there are no specific architectures,
|
||||
// just list the os entries.
|
||||
if len(p.GOARCH) == 0 {
|
||||
platforms[os] = true
|
||||
continue
|
||||
}
|
||||
// Otherwise, list all the os+arch combinations.
|
||||
for _, arch := range p.GOARCH {
|
||||
platforms[os+"/"+arch] = true
|
||||
}
|
||||
}
|
||||
// Cover the case where there are no specific
|
||||
// operating systems listed.
|
||||
if len(p.GOOS) == 0 {
|
||||
for _, arch := range p.GOARCH {
|
||||
platforms[arch] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var keys []string
|
||||
for k := range platforms {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
return keys
|
||||
}
|
||||
|
||||
func posToString(p *govulncheck.Position) string {
|
||||
if p == nil || p.Line <= 0 {
|
||||
return ""
|
||||
}
|
||||
return token.Position{
|
||||
Filename: AbsRelShorter(p.Filename),
|
||||
Offset: p.Offset,
|
||||
Line: p.Line,
|
||||
Column: p.Column,
|
||||
}.String()
|
||||
}
|
||||
|
||||
func symbol(frame *govulncheck.Frame, short bool) string {
|
||||
buf := &strings.Builder{}
|
||||
addSymbol(buf, frame, short)
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func symbolName(frame *govulncheck.Frame) string {
|
||||
buf := &strings.Builder{}
|
||||
addSymbolName(buf, frame)
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// compactTrace returns a short description of the call stack.
|
||||
// It prefers to show you the edge from the top module to other code, along with
|
||||
// the vulnerable symbol.
|
||||
// Where the vulnerable symbol directly called by the users code, it will only
|
||||
// show those two points.
|
||||
// If the vulnerable symbol is in the users code, it will show the entry point
|
||||
// and the vulnerable symbol.
|
||||
func compactTrace(finding *govulncheck.Finding) string {
|
||||
compact := traces.Compact(finding)
|
||||
if len(compact) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
l := len(compact)
|
||||
iTop := l - 1
|
||||
buf := &strings.Builder{}
|
||||
topPos := posToString(compact[iTop].Position)
|
||||
if topPos != "" {
|
||||
buf.WriteString(topPos)
|
||||
buf.WriteString(": ")
|
||||
}
|
||||
|
||||
if l > 1 {
|
||||
// print the root of the compact trace
|
||||
addSymbol(buf, compact[iTop], true)
|
||||
buf.WriteString(" calls ")
|
||||
}
|
||||
if l > 2 {
|
||||
// print next element of the trace, if any
|
||||
addSymbol(buf, compact[iTop-1], true)
|
||||
buf.WriteString(", which")
|
||||
if l > 3 {
|
||||
// don't print the third element, just acknowledge it
|
||||
buf.WriteString(" eventually")
|
||||
}
|
||||
buf.WriteString(" calls ")
|
||||
}
|
||||
addSymbol(buf, compact[0], true) // print the vulnerable symbol
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// notIdentifier reports whether ch is an invalid identifier character.
|
||||
func notIdentifier(ch rune) bool {
|
||||
return !('a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' ||
|
||||
'0' <= ch && ch <= '9' ||
|
||||
ch == '_' ||
|
||||
ch >= utf8.RuneSelf && (unicode.IsLetter(ch) || unicode.IsDigit(ch)))
|
||||
}
|
||||
|
||||
// importPathToAssumedName is taken from goimports, it works out the natural imported name
|
||||
// for a package.
|
||||
// This is used to get a shorter identifier in the compact stack trace
|
||||
func importPathToAssumedName(importPath string) string {
|
||||
base := path.Base(importPath)
|
||||
if strings.HasPrefix(base, "v") {
|
||||
if _, err := strconv.Atoi(base[1:]); err == nil {
|
||||
dir := path.Dir(importPath)
|
||||
if dir != "." {
|
||||
base = path.Base(dir)
|
||||
}
|
||||
}
|
||||
}
|
||||
base = strings.TrimPrefix(base, "go-")
|
||||
if i := strings.IndexFunc(base, notIdentifier); i >= 0 {
|
||||
base = base[:i]
|
||||
}
|
||||
return base
|
||||
}
|
||||
|
||||
func addSymbol(w io.Writer, frame *govulncheck.Frame, short bool) {
|
||||
if frame.Function == "" {
|
||||
return
|
||||
}
|
||||
if frame.Package != "" {
|
||||
pkg := frame.Package
|
||||
if short {
|
||||
pkg = importPathToAssumedName(frame.Package)
|
||||
}
|
||||
io.WriteString(w, pkg)
|
||||
io.WriteString(w, ".")
|
||||
}
|
||||
addSymbolName(w, frame)
|
||||
}
|
||||
|
||||
func addSymbolName(w io.Writer, frame *govulncheck.Frame) {
|
||||
if frame.Receiver != "" {
|
||||
if frame.Receiver[0] == '*' {
|
||||
io.WriteString(w, frame.Receiver[1:])
|
||||
} else {
|
||||
io.WriteString(w, frame.Receiver)
|
||||
}
|
||||
io.WriteString(w, ".")
|
||||
}
|
||||
funcname := strings.Split(frame.Function, "$")[0]
|
||||
io.WriteString(w, funcname)
|
||||
}
|
||||
Reference in New Issue
Block a user