57 lines
1.8 KiB
Go
57 lines
1.8 KiB
Go
|
|
// Copyright 2021 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 vulncheck
|
||
|
|
|
||
|
|
import (
|
||
|
|
"strings"
|
||
|
|
|
||
|
|
"golang.org/x/tools/go/ssa"
|
||
|
|
)
|
||
|
|
|
||
|
|
// entryPoints returns functions of topPackages considered entry
|
||
|
|
// points of govulncheck analysis: main, inits, and exported methods
|
||
|
|
// and functions.
|
||
|
|
//
|
||
|
|
// TODO(https://go.dev/issue/57221): currently, entry functions
|
||
|
|
// that are generics are not considered an entry point.
|
||
|
|
func entryPoints(topPackages []*ssa.Package) []*ssa.Function {
|
||
|
|
var entries []*ssa.Function
|
||
|
|
for _, pkg := range topPackages {
|
||
|
|
if pkg.Pkg.Name() == "main" {
|
||
|
|
// for "main" packages the only valid entry points are the "main"
|
||
|
|
// function and any "init#" functions, even if there are other
|
||
|
|
// exported functions or types. similarly to isEntry it should be
|
||
|
|
// safe to ignore the validity of the main or init# signatures,
|
||
|
|
// since the compiler will reject malformed definitions,
|
||
|
|
// and the init function is synthetic
|
||
|
|
entries = append(entries, memberFuncs(pkg.Members["main"], pkg.Prog)...)
|
||
|
|
for name, member := range pkg.Members {
|
||
|
|
if strings.HasPrefix(name, "init#") || name == "init" {
|
||
|
|
entries = append(entries, memberFuncs(member, pkg.Prog)...)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
for _, member := range pkg.Members {
|
||
|
|
for _, f := range memberFuncs(member, pkg.Prog) {
|
||
|
|
if isEntry(f) {
|
||
|
|
entries = append(entries, f)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return entries
|
||
|
|
}
|
||
|
|
|
||
|
|
func isEntry(f *ssa.Function) bool {
|
||
|
|
// it should be safe to ignore checking that the signature of the "init" function
|
||
|
|
// is valid, since it is synthetic
|
||
|
|
if f.Name() == "init" && f.Synthetic == "package initializer" {
|
||
|
|
return true
|
||
|
|
}
|
||
|
|
|
||
|
|
return f.Synthetic == "" && f.Object() != nil && f.Object().Exported()
|
||
|
|
}
|