// 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 ( "context" "fmt" "golang.org/x/tools/go/packages" "golang.org/x/vuln/internal/client" "golang.org/x/vuln/internal/derrors" "golang.org/x/vuln/internal/govulncheck" "golang.org/x/vuln/internal/vulncheck" ) // runSource reports vulnerabilities that affect the analyzed packages. // // Vulnerabilities can be called (affecting the package, because a vulnerable // symbol is actually exercised) or just imported by the package // (likely having a non-affecting outcome). func runSource(ctx context.Context, handler govulncheck.Handler, cfg *config, client *client.Client, dir string) (err error) { defer derrors.Wrap(&err, "govulncheck") if cfg.ScanLevel.WantPackages() && len(cfg.patterns) == 0 { return nil // don't throw an error here } if !gomodExists(dir) { return errNoGoMod } graph := vulncheck.NewPackageGraph(cfg.GoVersion) pkgConfig := &packages.Config{ Dir: dir, Tests: cfg.test, Env: cfg.env, } if err := graph.LoadPackagesAndMods(pkgConfig, cfg.tags, cfg.patterns, cfg.ScanLevel == govulncheck.ScanLevelSymbol); err != nil { if isGoVersionMismatchError(err) { return fmt.Errorf("%v\n\n%v", errGoVersionMismatch, err) } return fmt.Errorf("loading packages: %w", err) } if cfg.ScanLevel.WantPackages() && len(graph.TopPkgs()) == 0 { return nil // early exit } return vulncheck.Source(ctx, handler, &cfg.Config, client, graph) }