mirror of
https://github.com/anchore/syft.git
synced 2026-11-03 07:56:36 +01:00
feat: add h1digest when scanning go.mod (#1405)
Fixes https://github.com/anchore/syft/issues/1277
This commit is contained in:
@@ -1,12 +1,15 @@
|
||||
package golang
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/mod/modfile"
|
||||
|
||||
"github.com/anchore/syft/internal/log"
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/generic"
|
||||
@@ -14,7 +17,7 @@ import (
|
||||
)
|
||||
|
||||
// parseGoModFile takes a go.mod and lists all packages discovered.
|
||||
func parseGoModFile(_ source.FileResolver, _ *generic.Environment, reader source.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
func parseGoModFile(resolver source.FileResolver, _ *generic.Environment, reader source.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
packages := make(map[string]pkg.Package)
|
||||
|
||||
contents, err := io.ReadAll(reader)
|
||||
@@ -27,26 +30,39 @@ func parseGoModFile(_ source.FileResolver, _ *generic.Environment, reader source
|
||||
return nil, nil, fmt.Errorf("failed to parse go module: %w", err)
|
||||
}
|
||||
|
||||
digests, err := parseGoSumFile(resolver, reader)
|
||||
if err != nil {
|
||||
log.Debugf("unable to get go.sum: %v", err)
|
||||
}
|
||||
|
||||
for _, m := range file.Require {
|
||||
packages[m.Mod.Path] = pkg.Package{
|
||||
Name: m.Mod.Path,
|
||||
Version: m.Mod.Version,
|
||||
Locations: source.NewLocationSet(reader.Location),
|
||||
PURL: packageURL(m.Mod.Path, m.Mod.Version),
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Name: m.Mod.Path,
|
||||
Version: m.Mod.Version,
|
||||
Locations: source.NewLocationSet(reader.Location),
|
||||
PURL: packageURL(m.Mod.Path, m.Mod.Version),
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
MetadataType: pkg.GolangMetadataType,
|
||||
Metadata: pkg.GolangMetadata{
|
||||
H1Digest: digests[fmt.Sprintf("%s %s", m.Mod.Path, m.Mod.Version)],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// remove any old packages and replace with new ones...
|
||||
for _, m := range file.Replace {
|
||||
packages[m.New.Path] = pkg.Package{
|
||||
Name: m.New.Path,
|
||||
Version: m.New.Version,
|
||||
Locations: source.NewLocationSet(reader.Location),
|
||||
PURL: packageURL(m.New.Path, m.New.Version),
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Name: m.New.Path,
|
||||
Version: m.New.Version,
|
||||
Locations: source.NewLocationSet(reader.Location),
|
||||
PURL: packageURL(m.New.Path, m.New.Version),
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
MetadataType: pkg.GolangMetadataType,
|
||||
Metadata: pkg.GolangMetadata{
|
||||
H1Digest: digests[fmt.Sprintf("%s %s", m.New.Path, m.New.Version)],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,3 +85,40 @@ func parseGoModFile(_ source.FileResolver, _ *generic.Environment, reader source
|
||||
|
||||
return pkgsSlice, nil, nil
|
||||
}
|
||||
|
||||
func parseGoSumFile(resolver source.FileResolver, reader source.LocationReadCloser) (map[string]string, error) {
|
||||
out := map[string]string{}
|
||||
|
||||
if resolver == nil {
|
||||
return out, fmt.Errorf("no resolver provided")
|
||||
}
|
||||
|
||||
goSumPath := strings.TrimSuffix(reader.Location.RealPath, ".mod") + ".sum"
|
||||
goSumLocation := resolver.RelativeFileByPath(reader.Location, goSumPath)
|
||||
if goSumLocation == nil {
|
||||
return nil, fmt.Errorf("unable to resolve: %s", goSumPath)
|
||||
}
|
||||
contents, err := resolver.FileContentsByLocation(*goSumLocation)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// go.sum has the format like:
|
||||
// github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
// github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
|
||||
// github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
scanner := bufio.NewScanner(contents)
|
||||
// optionally, resize scanner's capacity for lines over 64K, see next example
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
parts := strings.Split(line, " ")
|
||||
if len(parts) < 3 {
|
||||
continue
|
||||
}
|
||||
nameVersion := fmt.Sprintf("%s %s", parts[0], parts[1])
|
||||
hash := parts[2]
|
||||
out[nameVersion] = hash
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user