61 lines
1.5 KiB
Go
61 lines
1.5 KiB
Go
// Copyright 2023 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 (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"sort"
|
|
|
|
"golang.org/x/vuln/internal/derrors"
|
|
"golang.org/x/vuln/internal/vulncheck"
|
|
)
|
|
|
|
const (
|
|
// extractModeID is the unique name of the extract mode protocol
|
|
extractModeID = "govulncheck-extract"
|
|
extractModeVersion = "0.1.0"
|
|
)
|
|
|
|
// header information for the blob output.
|
|
type header struct {
|
|
Name string `json:"name"`
|
|
Version string `json:"version"`
|
|
}
|
|
|
|
// runExtract dumps the extracted abstraction of binary at cfg.patterns to out.
|
|
// It prints out exactly two blob messages, one with the header and one with
|
|
// the vulncheck.Bin as the body.
|
|
func runExtract(cfg *config, out io.Writer) (err error) {
|
|
defer derrors.Wrap(&err, "govulncheck")
|
|
|
|
bin, err := createBin(cfg.patterns[0])
|
|
if err != nil {
|
|
return err
|
|
}
|
|
sortBin(bin) // sort for easier testing and validation
|
|
header := header{
|
|
Name: extractModeID,
|
|
Version: extractModeVersion,
|
|
}
|
|
|
|
enc := json.NewEncoder(out)
|
|
|
|
if err := enc.Encode(header); err != nil {
|
|
return fmt.Errorf("marshaling blob header: %v", err)
|
|
}
|
|
if err := enc.Encode(bin); err != nil {
|
|
return fmt.Errorf("marshaling blob body: %v", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func sortBin(bin *vulncheck.Bin) {
|
|
sort.SliceStable(bin.PkgSymbols, func(i, j int) bool {
|
|
return bin.PkgSymbols[i].Pkg+"."+bin.PkgSymbols[i].Name < bin.PkgSymbols[j].Pkg+"."+bin.PkgSymbols[j].Name
|
|
})
|
|
}
|