| // 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" |
| ) |
| |
| 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() |
| } |