blob: 97a808fcacda9a80995092f976efa9d40674990f [file] [log] [blame]
// 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.
// This program runs govulncheck on a module or a binary and then
// writes the result as JSON. It is intended to be run in a sandbox.
//
// Unless it panics, this program always terminates with exit code 0.
// If there is an error, it writes a JSON object with field "Error".
// Otherwise, it writes a internal/govulncheck.SandboxResponse as JSON.
package main
import (
"encoding/json"
"errors"
"flag"
"fmt"
"io"
"os"
"golang.org/x/pkgsite-metrics/internal/govulncheck"
"golang.org/x/pkgsite-metrics/internal/worker"
)
// main function for govulncheck sandbox that accepts four inputs
// in the following order:
// - path to govulncheck
// - govulncheck mode
// - input module or binary to analyze
// - full path to the vulnerability database
func main() {
flag.Parse()
run(os.Stdout, flag.Args())
}
func run(w io.Writer, args []string) {
fail := func(err error) {
fmt.Fprintf(w, `{"Error": %q}`, err)
fmt.Fprintln(w)
}
if len(args) != 4 {
fail(errors.New("need four args: govulncheck path, mode, input module dir or binary, full path to vuln db"))
return
}
mode := args[1]
if !worker.IsValidGovulncheckMode(mode) {
fail(fmt.Errorf("%q is not a valid mode", mode))
return
}
resp, err := runGovulncheck(args[0], mode, args[2], args[3])
if err != nil {
fail(err)
return
}
b, err := json.MarshalIndent(resp, "", "\t")
if err != nil {
fail(fmt.Errorf("json.MarshalIndent: %v", err))
return
}
w.Write(b)
fmt.Println()
}
func runGovulncheck(govulncheckPath, mode, filePath, vulnDBDir string) (*govulncheck.SandboxResponse, error) {
response := govulncheck.SandboxResponse{
Stats: govulncheck.ScanStats{},
}
var modeFlag, pattern string
switch mode {
case govulncheck.ModeBinary:
modeFlag = govulncheck.FlagBinary
pattern = filePath
case govulncheck.ModeGovulncheck:
modeFlag = govulncheck.FlagSource
pattern = "./..."
}
findings, err := govulncheck.RunGovulncheckCmd(govulncheckPath, modeFlag, pattern, filePath, vulnDBDir, &response.Stats)
if err != nil {
return nil, err
}
response.Findings = findings
return &response, nil
}