mirror of
https://github.com/anchore/syft.git
synced 2026-02-12 10:36:45 +01:00
feat: add h1digest when scanning go.mod (#1405)
Fixes https://github.com/anchore/syft/issues/1277
This commit is contained in:
parent
82f32c7301
commit
7b08608adb
@ -37,7 +37,7 @@ type artifactMetadataContainer struct {
|
|||||||
Python pkg.PythonPackageMetadata
|
Python pkg.PythonPackageMetadata
|
||||||
Rpm pkg.RpmMetadata
|
Rpm pkg.RpmMetadata
|
||||||
Cargo pkg.CargoPackageMetadata
|
Cargo pkg.CargoPackageMetadata
|
||||||
Go pkg.GolangBinMetadata
|
Go pkg.GolangMetadata
|
||||||
Php pkg.PhpComposerJSONMetadata
|
Php pkg.PhpComposerJSONMetadata
|
||||||
Dart pkg.DartPubMetadata
|
Dart pkg.DartPubMetadata
|
||||||
Dotnet pkg.DotnetDepsMetadata
|
Dotnet pkg.DotnetDepsMetadata
|
||||||
|
|||||||
@ -90,8 +90,8 @@ func Test_encodeComponentProperties(t *testing.T) {
|
|||||||
Version: "v0.0.0-20211006190231-62292e806868",
|
Version: "v0.0.0-20211006190231-62292e806868",
|
||||||
Language: pkg.Go,
|
Language: pkg.Go,
|
||||||
Type: pkg.GoModulePkg,
|
Type: pkg.GoModulePkg,
|
||||||
MetadataType: pkg.GolangBinMetadataType,
|
MetadataType: pkg.GolangMetadataType,
|
||||||
Metadata: pkg.GolangBinMetadata{
|
Metadata: pkg.GolangMetadata{
|
||||||
GoCompiledVersion: "1.17",
|
GoCompiledVersion: "1.17",
|
||||||
Architecture: "amd64",
|
Architecture: "amd64",
|
||||||
H1Digest: "h1:KlOXYy8wQWTUJYFgkUI40Lzr06ofg5IRXUK5C7qZt1k=",
|
H1Digest: "h1:KlOXYy8wQWTUJYFgkUI40Lzr06ofg5IRXUK5C7qZt1k=",
|
||||||
@ -99,7 +99,7 @@ func Test_encodeComponentProperties(t *testing.T) {
|
|||||||
},
|
},
|
||||||
expected: &[]cyclonedx.Property{
|
expected: &[]cyclonedx.Property{
|
||||||
{Name: "syft:package:language", Value: pkg.Go.String()},
|
{Name: "syft:package:language", Value: pkg.Go.String()},
|
||||||
{Name: "syft:package:metadataType", Value: "GolangBinMetadata"},
|
{Name: "syft:package:metadataType", Value: "GolangMetadata"},
|
||||||
{Name: "syft:package:type", Value: "go-module"},
|
{Name: "syft:package:type", Value: "go-module"},
|
||||||
{Name: "syft:metadata:architecture", Value: "amd64"},
|
{Name: "syft:metadata:architecture", Value: "amd64"},
|
||||||
{Name: "syft:metadata:goCompiledVersion", Value: "1.17"},
|
{Name: "syft:metadata:goCompiledVersion", Value: "1.17"},
|
||||||
|
|||||||
@ -313,7 +313,7 @@ func toPackageChecksums(p pkg.Package) ([]common.Checksum, bool) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case pkg.GolangBinMetadata:
|
case pkg.GolangMetadata:
|
||||||
// because the H1 digest is found in the Golang metadata we cannot claim that the files were analyzed
|
// because the H1 digest is found in the Golang metadata we cannot claim that the files were analyzed
|
||||||
algo, hexStr, err := util.HDigestToSHA(meta.H1Digest)
|
algo, hexStr, err := util.HDigestToSHA(meta.H1Digest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -76,8 +76,8 @@ func Test_toPackageChecksums(t *testing.T) {
|
|||||||
Name: "test",
|
Name: "test",
|
||||||
Version: "1.0.0",
|
Version: "1.0.0",
|
||||||
Language: pkg.Go,
|
Language: pkg.Go,
|
||||||
MetadataType: pkg.GolangBinMetadataType,
|
MetadataType: pkg.GolangMetadataType,
|
||||||
Metadata: pkg.GolangBinMetadata{
|
Metadata: pkg.GolangMetadata{
|
||||||
H1Digest: "h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw=",
|
H1Digest: "h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw=",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -381,8 +381,8 @@ func Test_H1Digest(t *testing.T) {
|
|||||||
pkg: pkg.Package{
|
pkg: pkg.Package{
|
||||||
Name: "github.com/googleapis/gnostic",
|
Name: "github.com/googleapis/gnostic",
|
||||||
Version: "v0.5.5",
|
Version: "v0.5.5",
|
||||||
MetadataType: pkg.GolangBinMetadataType,
|
MetadataType: pkg.GolangMetadataType,
|
||||||
Metadata: pkg.GolangBinMetadata{
|
Metadata: pkg.GolangMetadata{
|
||||||
H1Digest: "h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw=",
|
H1Digest: "h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw=",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -393,8 +393,8 @@ func Test_H1Digest(t *testing.T) {
|
|||||||
pkg: pkg.Package{
|
pkg: pkg.Package{
|
||||||
Name: "github.com/googleapis/gnostic",
|
Name: "github.com/googleapis/gnostic",
|
||||||
Version: "v0.5.5",
|
Version: "v0.5.5",
|
||||||
MetadataType: pkg.GolangBinMetadataType,
|
MetadataType: pkg.GolangMetadataType,
|
||||||
Metadata: pkg.GolangBinMetadata{
|
Metadata: pkg.GolangMetadata{
|
||||||
H1Digest: "h1:9fHAtK0uzzz",
|
H1Digest: "h1:9fHAtK0uzzz",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -405,8 +405,8 @@ func Test_H1Digest(t *testing.T) {
|
|||||||
pkg: pkg.Package{
|
pkg: pkg.Package{
|
||||||
Name: "github.com/googleapis/gnostic",
|
Name: "github.com/googleapis/gnostic",
|
||||||
Version: "v0.5.5",
|
Version: "v0.5.5",
|
||||||
MetadataType: pkg.GolangBinMetadataType,
|
MetadataType: pkg.GolangMetadataType,
|
||||||
Metadata: pkg.GolangBinMetadata{
|
Metadata: pkg.GolangMetadata{
|
||||||
H1Digest: "h12:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw=",
|
H1Digest: "h12:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw=",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -365,7 +365,7 @@ func extractMetadata(p *spdx.Package, info pkgInfo) (pkg.MetadataType, interface
|
|||||||
h1Digest = digest
|
h1Digest = digest
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return pkg.GolangBinMetadataType, pkg.GolangBinMetadata{
|
return pkg.GolangMetadataType, pkg.GolangMetadata{
|
||||||
H1Digest: h1Digest,
|
H1Digest: h1Digest,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -302,8 +302,8 @@ func TestH1Digest(t *testing.T) {
|
|||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
p := toSyftPackage(&test.pkg)
|
p := toSyftPackage(&test.pkg)
|
||||||
require.Equal(t, pkg.GolangBinMetadataType, p.MetadataType)
|
require.Equal(t, pkg.GolangMetadataType, p.MetadataType)
|
||||||
meta := p.Metadata.(pkg.GolangBinMetadata)
|
meta := p.Metadata.(pkg.GolangMetadata)
|
||||||
require.Equal(t, test.expectedDigest, meta.H1Digest)
|
require.Equal(t, test.expectedDigest, meta.H1Digest)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,7 +34,7 @@ func TestUnmarshalPackageGolang(t *testing.T) {
|
|||||||
"language": "go",
|
"language": "go",
|
||||||
"cpes": [],
|
"cpes": [],
|
||||||
"purl": "pkg:golang/gopkg.in/square/go-jose.v2@v2.6.0",
|
"purl": "pkg:golang/gopkg.in/square/go-jose.v2@v2.6.0",
|
||||||
"metadataType": "GolangBinMetadata",
|
"metadataType": "GolangMetadata",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"goCompiledVersion": "go1.18",
|
"goCompiledVersion": "go1.18",
|
||||||
"architecture": "amd64",
|
"architecture": "amd64",
|
||||||
@ -43,7 +43,7 @@ func TestUnmarshalPackageGolang(t *testing.T) {
|
|||||||
}`),
|
}`),
|
||||||
assert: func(p *Package) {
|
assert: func(p *Package) {
|
||||||
assert.NotNil(t, p.Metadata)
|
assert.NotNil(t, p.Metadata)
|
||||||
golangMetadata := p.Metadata.(pkg.GolangBinMetadata)
|
golangMetadata := p.Metadata.(pkg.GolangMetadata)
|
||||||
assert.NotEmpty(t, golangMetadata)
|
assert.NotEmpty(t, golangMetadata)
|
||||||
assert.Equal(t, "go1.18", golangMetadata.GoCompiledVersion)
|
assert.Equal(t, "go1.18", golangMetadata.GoCompiledVersion)
|
||||||
},
|
},
|
||||||
@ -93,7 +93,7 @@ func Test_unpackMetadata(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "unmarshal package metadata",
|
name: "unmarshal package metadata",
|
||||||
metadataType: pkg.GolangBinMetadataType,
|
metadataType: pkg.GolangMetadataType,
|
||||||
packageData: []byte(`{
|
packageData: []byte(`{
|
||||||
"id": "8b594519bc23da50",
|
"id": "8b594519bc23da50",
|
||||||
"name": "gopkg.in/square/go-jose.v2",
|
"name": "gopkg.in/square/go-jose.v2",
|
||||||
@ -109,7 +109,7 @@ func Test_unpackMetadata(t *testing.T) {
|
|||||||
"language": "go",
|
"language": "go",
|
||||||
"cpes": [],
|
"cpes": [],
|
||||||
"purl": "pkg:golang/gopkg.in/square/go-jose.v2@v2.6.0",
|
"purl": "pkg:golang/gopkg.in/square/go-jose.v2@v2.6.0",
|
||||||
"metadataType": "GolangBinMetadata",
|
"metadataType": "GolangMetadata",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"goCompiledVersion": "go1.18",
|
"goCompiledVersion": "go1.18",
|
||||||
"architecture": "amd64",
|
"architecture": "amd64",
|
||||||
@ -214,11 +214,19 @@ func Test_unpackMetadata(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "can handle package with metadata type but missing metadata",
|
name: "can handle package with metadata type but missing metadata",
|
||||||
|
packageData: []byte(`{
|
||||||
|
"metadataType": "GolangMetadata"
|
||||||
|
}`),
|
||||||
|
metadataType: pkg.GolangMetadataType,
|
||||||
|
wantMetadata: pkg.GolangMetadata{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "can handle package with golang bin metadata type",
|
||||||
packageData: []byte(`{
|
packageData: []byte(`{
|
||||||
"metadataType": "GolangBinMetadata"
|
"metadataType": "GolangBinMetadata"
|
||||||
}`),
|
}`),
|
||||||
metadataType: pkg.GolangBinMetadataType,
|
metadataType: pkg.GolangMetadataType,
|
||||||
wantMetadata: pkg.GolangBinMetadata{},
|
wantMetadata: pkg.GolangMetadata{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "can handle package with unknonwn metadata type and missing metadata",
|
name: "can handle package with unknonwn metadata type and missing metadata",
|
||||||
|
|||||||
@ -22,8 +22,8 @@ func newGoBinaryPackage(dep *debug.Module, mainModule, goVersion, architecture s
|
|||||||
Language: pkg.Go,
|
Language: pkg.Go,
|
||||||
Type: pkg.GoModulePkg,
|
Type: pkg.GoModulePkg,
|
||||||
Locations: source.NewLocationSet(locations...),
|
Locations: source.NewLocationSet(locations...),
|
||||||
MetadataType: pkg.GolangBinMetadataType,
|
MetadataType: pkg.GolangMetadataType,
|
||||||
Metadata: pkg.GolangBinMetadata{
|
Metadata: pkg.GolangMetadata{
|
||||||
GoCompiledVersion: goVersion,
|
GoCompiledVersion: goVersion,
|
||||||
H1Digest: dep.Sum,
|
H1Digest: dep.Sum,
|
||||||
Architecture: architecture,
|
Architecture: architecture,
|
||||||
|
|||||||
@ -143,8 +143,8 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
MetadataType: pkg.GolangBinMetadataType,
|
MetadataType: pkg.GolangMetadataType,
|
||||||
Metadata: pkg.GolangBinMetadata{
|
Metadata: pkg.GolangMetadata{
|
||||||
GoCompiledVersion: goCompiledVersion,
|
GoCompiledVersion: goCompiledVersion,
|
||||||
Architecture: archDetails,
|
Architecture: archDetails,
|
||||||
BuildSettings: defaultBuildSettings,
|
BuildSettings: defaultBuildSettings,
|
||||||
@ -190,8 +190,8 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
MetadataType: pkg.GolangBinMetadataType,
|
MetadataType: pkg.GolangMetadataType,
|
||||||
Metadata: pkg.GolangBinMetadata{},
|
Metadata: pkg.GolangMetadata{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -233,8 +233,8 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
MetadataType: pkg.GolangBinMetadataType,
|
MetadataType: pkg.GolangMetadataType,
|
||||||
Metadata: pkg.GolangBinMetadata{
|
Metadata: pkg.GolangMetadata{
|
||||||
GoCompiledVersion: goCompiledVersion,
|
GoCompiledVersion: goCompiledVersion,
|
||||||
Architecture: archDetails,
|
Architecture: archDetails,
|
||||||
H1Digest: "h1:VSVdnH7cQ7V+B33qSJHTCRlNgra1607Q8PzEmnvb2Ic=",
|
H1Digest: "h1:VSVdnH7cQ7V+B33qSJHTCRlNgra1607Q8PzEmnvb2Ic=",
|
||||||
@ -285,8 +285,8 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
MetadataType: pkg.GolangBinMetadataType,
|
MetadataType: pkg.GolangMetadataType,
|
||||||
Metadata: pkg.GolangBinMetadata{
|
Metadata: pkg.GolangMetadata{
|
||||||
GoCompiledVersion: goCompiledVersion,
|
GoCompiledVersion: goCompiledVersion,
|
||||||
Architecture: archDetails,
|
Architecture: archDetails,
|
||||||
BuildSettings: map[string]string{
|
BuildSettings: map[string]string{
|
||||||
@ -340,8 +340,8 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
MetadataType: pkg.GolangBinMetadataType,
|
MetadataType: pkg.GolangMetadataType,
|
||||||
Metadata: pkg.GolangBinMetadata{
|
Metadata: pkg.GolangMetadata{
|
||||||
GoCompiledVersion: goCompiledVersion,
|
GoCompiledVersion: goCompiledVersion,
|
||||||
Architecture: archDetails,
|
Architecture: archDetails,
|
||||||
H1Digest: "h1:VSVdnH7cQ7V+B33qSJHTCRlNgra1607Q8PzEmnvb2Ic=",
|
H1Digest: "h1:VSVdnH7cQ7V+B33qSJHTCRlNgra1607Q8PzEmnvb2Ic=",
|
||||||
@ -362,8 +362,8 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
MetadataType: pkg.GolangBinMetadataType,
|
MetadataType: pkg.GolangMetadataType,
|
||||||
Metadata: pkg.GolangBinMetadata{
|
Metadata: pkg.GolangMetadata{
|
||||||
GoCompiledVersion: goCompiledVersion,
|
GoCompiledVersion: goCompiledVersion,
|
||||||
Architecture: archDetails,
|
Architecture: archDetails,
|
||||||
H1Digest: "h1:DYssiUV1pBmKqzKsm4mqXx8artqC0Q8HgZsVI3lMsAg=",
|
H1Digest: "h1:DYssiUV1pBmKqzKsm4mqXx8artqC0Q8HgZsVI3lMsAg=",
|
||||||
@ -417,8 +417,8 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
MetadataType: pkg.GolangBinMetadataType,
|
MetadataType: pkg.GolangMetadataType,
|
||||||
Metadata: pkg.GolangBinMetadata{
|
Metadata: pkg.GolangMetadata{
|
||||||
GoCompiledVersion: goCompiledVersion,
|
GoCompiledVersion: goCompiledVersion,
|
||||||
Architecture: archDetails,
|
Architecture: archDetails,
|
||||||
H1Digest: "h1:PjhxBct4MZii8FFR8+oeS7QOvxKOTZXgk63EU2XpfJE=",
|
H1Digest: "h1:PjhxBct4MZii8FFR8+oeS7QOvxKOTZXgk63EU2XpfJE=",
|
||||||
@ -438,8 +438,8 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
MetadataType: pkg.GolangBinMetadataType,
|
MetadataType: pkg.GolangMetadataType,
|
||||||
Metadata: pkg.GolangBinMetadata{
|
Metadata: pkg.GolangMetadata{
|
||||||
GoCompiledVersion: goCompiledVersion,
|
GoCompiledVersion: goCompiledVersion,
|
||||||
Architecture: archDetails,
|
Architecture: archDetails,
|
||||||
H1Digest: "h1:Ihq/mm/suC88gF8WFcVwk+OV6Tq+wyA1O0E5UEvDglI=",
|
H1Digest: "h1:Ihq/mm/suC88gF8WFcVwk+OV6Tq+wyA1O0E5UEvDglI=",
|
||||||
|
|||||||
@ -1,12 +1,15 @@
|
|||||||
package golang
|
package golang
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"golang.org/x/mod/modfile"
|
"golang.org/x/mod/modfile"
|
||||||
|
|
||||||
|
"github.com/anchore/syft/internal/log"
|
||||||
"github.com/anchore/syft/syft/artifact"
|
"github.com/anchore/syft/syft/artifact"
|
||||||
"github.com/anchore/syft/syft/pkg"
|
"github.com/anchore/syft/syft/pkg"
|
||||||
"github.com/anchore/syft/syft/pkg/cataloger/generic"
|
"github.com/anchore/syft/syft/pkg/cataloger/generic"
|
||||||
@ -14,7 +17,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// parseGoModFile takes a go.mod and lists all packages discovered.
|
// 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)
|
packages := make(map[string]pkg.Package)
|
||||||
|
|
||||||
contents, err := io.ReadAll(reader)
|
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)
|
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 {
|
for _, m := range file.Require {
|
||||||
packages[m.Mod.Path] = pkg.Package{
|
packages[m.Mod.Path] = pkg.Package{
|
||||||
Name: m.Mod.Path,
|
Name: m.Mod.Path,
|
||||||
Version: m.Mod.Version,
|
Version: m.Mod.Version,
|
||||||
Locations: source.NewLocationSet(reader.Location),
|
Locations: source.NewLocationSet(reader.Location),
|
||||||
PURL: packageURL(m.Mod.Path, m.Mod.Version),
|
PURL: packageURL(m.Mod.Path, m.Mod.Version),
|
||||||
Language: pkg.Go,
|
Language: pkg.Go,
|
||||||
Type: pkg.GoModulePkg,
|
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...
|
// remove any old packages and replace with new ones...
|
||||||
for _, m := range file.Replace {
|
for _, m := range file.Replace {
|
||||||
packages[m.New.Path] = pkg.Package{
|
packages[m.New.Path] = pkg.Package{
|
||||||
Name: m.New.Path,
|
Name: m.New.Path,
|
||||||
Version: m.New.Version,
|
Version: m.New.Version,
|
||||||
Locations: source.NewLocationSet(reader.Location),
|
Locations: source.NewLocationSet(reader.Location),
|
||||||
PURL: packageURL(m.New.Path, m.New.Version),
|
PURL: packageURL(m.New.Path, m.New.Version),
|
||||||
Language: pkg.Go,
|
Language: pkg.Go,
|
||||||
Type: pkg.GoModulePkg,
|
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
|
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
|
||||||
|
}
|
||||||
|
|||||||
@ -17,12 +17,14 @@ func TestParseGoMod(t *testing.T) {
|
|||||||
fixture: "test-fixtures/one-package",
|
fixture: "test-fixtures/one-package",
|
||||||
expected: []pkg.Package{
|
expected: []pkg.Package{
|
||||||
{
|
{
|
||||||
Name: "github.com/bmatcuk/doublestar",
|
Name: "github.com/bmatcuk/doublestar",
|
||||||
Version: "v1.3.1",
|
Version: "v1.3.1",
|
||||||
PURL: "pkg:golang/github.com/bmatcuk/doublestar@v1.3.1",
|
PURL: "pkg:golang/github.com/bmatcuk/doublestar@v1.3.1",
|
||||||
Locations: source.NewLocationSet(source.NewLocation("test-fixtures/one-package")),
|
Locations: source.NewLocationSet(source.NewLocation("test-fixtures/one-package")),
|
||||||
Language: pkg.Go,
|
Language: pkg.Go,
|
||||||
Type: pkg.GoModulePkg,
|
Type: pkg.GoModulePkg,
|
||||||
|
MetadataType: pkg.GolangMetadataType,
|
||||||
|
Metadata: pkg.GolangMetadata{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -31,44 +33,54 @@ func TestParseGoMod(t *testing.T) {
|
|||||||
fixture: "test-fixtures/many-packages",
|
fixture: "test-fixtures/many-packages",
|
||||||
expected: []pkg.Package{
|
expected: []pkg.Package{
|
||||||
{
|
{
|
||||||
Name: "github.com/anchore/go-testutils",
|
Name: "github.com/anchore/go-testutils",
|
||||||
Version: "v0.0.0-20200624184116-66aa578126db",
|
Version: "v0.0.0-20200624184116-66aa578126db",
|
||||||
PURL: "pkg:golang/github.com/anchore/go-testutils@v0.0.0-20200624184116-66aa578126db",
|
PURL: "pkg:golang/github.com/anchore/go-testutils@v0.0.0-20200624184116-66aa578126db",
|
||||||
Locations: source.NewLocationSet(source.NewLocation("test-fixtures/many-packages")),
|
Locations: source.NewLocationSet(source.NewLocation("test-fixtures/many-packages")),
|
||||||
Language: pkg.Go,
|
Language: pkg.Go,
|
||||||
Type: pkg.GoModulePkg,
|
Type: pkg.GoModulePkg,
|
||||||
|
MetadataType: pkg.GolangMetadataType,
|
||||||
|
Metadata: pkg.GolangMetadata{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "github.com/anchore/go-version",
|
Name: "github.com/anchore/go-version",
|
||||||
Version: "v1.2.2-0.20200701162849-18adb9c92b9b",
|
Version: "v1.2.2-0.20200701162849-18adb9c92b9b",
|
||||||
PURL: "pkg:golang/github.com/anchore/go-version@v1.2.2-0.20200701162849-18adb9c92b9b",
|
PURL: "pkg:golang/github.com/anchore/go-version@v1.2.2-0.20200701162849-18adb9c92b9b",
|
||||||
Locations: source.NewLocationSet(source.NewLocation("test-fixtures/many-packages")),
|
Locations: source.NewLocationSet(source.NewLocation("test-fixtures/many-packages")),
|
||||||
Language: pkg.Go,
|
Language: pkg.Go,
|
||||||
Type: pkg.GoModulePkg,
|
Type: pkg.GoModulePkg,
|
||||||
|
MetadataType: pkg.GolangMetadataType,
|
||||||
|
Metadata: pkg.GolangMetadata{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "github.com/anchore/stereoscope",
|
Name: "github.com/anchore/stereoscope",
|
||||||
Version: "v0.0.0-20200706164556-7cf39d7f4639",
|
Version: "v0.0.0-20200706164556-7cf39d7f4639",
|
||||||
PURL: "pkg:golang/github.com/anchore/stereoscope@v0.0.0-20200706164556-7cf39d7f4639",
|
PURL: "pkg:golang/github.com/anchore/stereoscope@v0.0.0-20200706164556-7cf39d7f4639",
|
||||||
Locations: source.NewLocationSet(source.NewLocation("test-fixtures/many-packages")),
|
Locations: source.NewLocationSet(source.NewLocation("test-fixtures/many-packages")),
|
||||||
Language: pkg.Go,
|
Language: pkg.Go,
|
||||||
Type: pkg.GoModulePkg,
|
Type: pkg.GoModulePkg,
|
||||||
|
MetadataType: pkg.GolangMetadataType,
|
||||||
|
Metadata: pkg.GolangMetadata{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "github.com/bmatcuk/doublestar",
|
Name: "github.com/bmatcuk/doublestar",
|
||||||
Version: "v8.8.8",
|
Version: "v8.8.8",
|
||||||
PURL: "pkg:golang/github.com/bmatcuk/doublestar@v8.8.8",
|
PURL: "pkg:golang/github.com/bmatcuk/doublestar@v8.8.8",
|
||||||
Locations: source.NewLocationSet(source.NewLocation("test-fixtures/many-packages")),
|
Locations: source.NewLocationSet(source.NewLocation("test-fixtures/many-packages")),
|
||||||
Language: pkg.Go,
|
Language: pkg.Go,
|
||||||
Type: pkg.GoModulePkg,
|
Type: pkg.GoModulePkg,
|
||||||
|
MetadataType: pkg.GolangMetadataType,
|
||||||
|
Metadata: pkg.GolangMetadata{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "github.com/go-test/deep",
|
Name: "github.com/go-test/deep",
|
||||||
Version: "v1.0.6",
|
Version: "v1.0.6",
|
||||||
PURL: "pkg:golang/github.com/go-test/deep@v1.0.6",
|
PURL: "pkg:golang/github.com/go-test/deep@v1.0.6",
|
||||||
Locations: source.NewLocationSet(source.NewLocation("test-fixtures/many-packages")),
|
Locations: source.NewLocationSet(source.NewLocation("test-fixtures/many-packages")),
|
||||||
Language: pkg.Go,
|
Language: pkg.Go,
|
||||||
Type: pkg.GoModulePkg,
|
Type: pkg.GoModulePkg,
|
||||||
|
MetadataType: pkg.GolangMetadataType,
|
||||||
|
Metadata: pkg.GolangMetadata{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -83,3 +95,62 @@ func TestParseGoMod(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_GoSumHashes(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
fixture string
|
||||||
|
expected []pkg.Package
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
fixture: "test-fixtures/go-sum-hashes",
|
||||||
|
expected: []pkg.Package{
|
||||||
|
{
|
||||||
|
Name: "github.com/CycloneDX/cyclonedx-go",
|
||||||
|
Version: "v0.6.0",
|
||||||
|
PURL: "pkg:golang/github.com/CycloneDX/cyclonedx-go@v0.6.0",
|
||||||
|
Locations: source.NewLocationSet(source.NewLocation("go.mod")),
|
||||||
|
FoundBy: "go-mod-file-cataloger",
|
||||||
|
Language: pkg.Go,
|
||||||
|
Type: pkg.GoModulePkg,
|
||||||
|
MetadataType: pkg.GolangMetadataType,
|
||||||
|
Metadata: pkg.GolangMetadata{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "github.com/acarl005/stripansi",
|
||||||
|
Version: "v0.0.0-20180116102854-5a71ef0e047d",
|
||||||
|
PURL: "pkg:golang/github.com/acarl005/stripansi@v0.0.0-20180116102854-5a71ef0e047d",
|
||||||
|
Locations: source.NewLocationSet(source.NewLocation("go.mod")),
|
||||||
|
FoundBy: "go-mod-file-cataloger",
|
||||||
|
Language: pkg.Go,
|
||||||
|
Type: pkg.GoModulePkg,
|
||||||
|
MetadataType: pkg.GolangMetadataType,
|
||||||
|
Metadata: pkg.GolangMetadata{
|
||||||
|
H1Digest: "h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "github.com/mgutz/ansi",
|
||||||
|
Version: "v0.0.0-20200706080929-d51e80ef957d",
|
||||||
|
PURL: "pkg:golang/github.com/mgutz/ansi@v0.0.0-20200706080929-d51e80ef957d",
|
||||||
|
Locations: source.NewLocationSet(source.NewLocation("go.mod")),
|
||||||
|
FoundBy: "go-mod-file-cataloger",
|
||||||
|
Language: pkg.Go,
|
||||||
|
Type: pkg.GoModulePkg,
|
||||||
|
MetadataType: pkg.GolangMetadataType,
|
||||||
|
Metadata: pkg.GolangMetadata{
|
||||||
|
H1Digest: "h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.fixture, func(t *testing.T) {
|
||||||
|
pkgtest.NewCatalogTester().
|
||||||
|
FromDirectory(t, test.fixture).
|
||||||
|
Expects(test.expected, nil).
|
||||||
|
TestCataloger(t, NewGoModFileCataloger())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
11
syft/pkg/cataloger/golang/test-fixtures/go-sum-hashes/go.mod
Normal file
11
syft/pkg/cataloger/golang/test-fixtures/go-sum-hashes/go.mod
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
module github.com/anchore/syft
|
||||||
|
|
||||||
|
go 1.18
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/CycloneDX/cyclonedx-go v0.7.0
|
||||||
|
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
|
||||||
|
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
|
||||||
|
)
|
||||||
|
|
||||||
|
replace github.com/CycloneDX/cyclonedx-go => github.com/CycloneDX/cyclonedx-go v0.6.0
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
github.com/CycloneDX/cyclonedx-go v0.7.0 h1:jNxp8hL7UpcvPDFXjY+Y1ibFtsW+e5zyF9QoSmhK/zg=
|
||||||
|
github.com/CycloneDX/cyclonedx-go v0.7.0/go.mod h1:W5Z9w8pTTL+t+yG3PCiFRGlr8PUlE0pGWzKSJbsyXkg=
|
||||||
|
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
|
||||||
|
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
|
||||||
|
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||||
|
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=
|
||||||
|
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package pkg
|
package pkg
|
||||||
|
|
||||||
// GolangBinMetadata represents all captured data for a Golang Binary
|
// GolangMetadata represents all captured data for a Golang Binary
|
||||||
type GolangBinMetadata struct {
|
type GolangMetadata struct {
|
||||||
BuildSettings map[string]string `json:"goBuildSettings,omitempty" cyclonedx:"goBuildSettings"`
|
BuildSettings map[string]string `json:"goBuildSettings,omitempty" cyclonedx:"goBuildSettings"`
|
||||||
GoCompiledVersion string `json:"goCompiledVersion" cyclonedx:"goCompiledVersion"`
|
GoCompiledVersion string `json:"goCompiledVersion" cyclonedx:"goCompiledVersion"`
|
||||||
Architecture string `json:"architecture" cyclonedx:"architecture"`
|
Architecture string `json:"architecture" cyclonedx:"architecture"`
|
||||||
@ -24,7 +24,7 @@ const (
|
|||||||
PythonPackageMetadataType MetadataType = "PythonPackageMetadata"
|
PythonPackageMetadataType MetadataType = "PythonPackageMetadata"
|
||||||
RustCargoPackageMetadataType MetadataType = "RustCargoPackageMetadata"
|
RustCargoPackageMetadataType MetadataType = "RustCargoPackageMetadata"
|
||||||
KbPackageMetadataType MetadataType = "KbPackageMetadata"
|
KbPackageMetadataType MetadataType = "KbPackageMetadata"
|
||||||
GolangBinMetadataType MetadataType = "GolangBinMetadata"
|
GolangMetadataType MetadataType = "GolangMetadata"
|
||||||
PhpComposerJSONMetadataType MetadataType = "PhpComposerJsonMetadata"
|
PhpComposerJSONMetadataType MetadataType = "PhpComposerJsonMetadata"
|
||||||
CocoapodsMetadataType MetadataType = "CocoapodsMetadataType"
|
CocoapodsMetadataType MetadataType = "CocoapodsMetadataType"
|
||||||
ConanMetadataType MetadataType = "ConanMetadataType"
|
ConanMetadataType MetadataType = "ConanMetadataType"
|
||||||
@ -47,7 +47,7 @@ var AllMetadataTypes = []MetadataType{
|
|||||||
PythonPackageMetadataType,
|
PythonPackageMetadataType,
|
||||||
RustCargoPackageMetadataType,
|
RustCargoPackageMetadataType,
|
||||||
KbPackageMetadataType,
|
KbPackageMetadataType,
|
||||||
GolangBinMetadataType,
|
GolangMetadataType,
|
||||||
PhpComposerJSONMetadataType,
|
PhpComposerJSONMetadataType,
|
||||||
CocoapodsMetadataType,
|
CocoapodsMetadataType,
|
||||||
ConanMetadataType,
|
ConanMetadataType,
|
||||||
@ -70,7 +70,7 @@ var MetadataTypeByName = map[MetadataType]reflect.Type{
|
|||||||
PythonPackageMetadataType: reflect.TypeOf(PythonPackageMetadata{}),
|
PythonPackageMetadataType: reflect.TypeOf(PythonPackageMetadata{}),
|
||||||
RustCargoPackageMetadataType: reflect.TypeOf(CargoPackageMetadata{}),
|
RustCargoPackageMetadataType: reflect.TypeOf(CargoPackageMetadata{}),
|
||||||
KbPackageMetadataType: reflect.TypeOf(KbPackageMetadata{}),
|
KbPackageMetadataType: reflect.TypeOf(KbPackageMetadata{}),
|
||||||
GolangBinMetadataType: reflect.TypeOf(GolangBinMetadata{}),
|
GolangMetadataType: reflect.TypeOf(GolangMetadata{}),
|
||||||
PhpComposerJSONMetadataType: reflect.TypeOf(PhpComposerJSONMetadata{}),
|
PhpComposerJSONMetadataType: reflect.TypeOf(PhpComposerJSONMetadata{}),
|
||||||
CocoapodsMetadataType: reflect.TypeOf(CocoapodsMetadata{}),
|
CocoapodsMetadataType: reflect.TypeOf(CocoapodsMetadata{}),
|
||||||
ConanMetadataType: reflect.TypeOf(ConanMetadata{}),
|
ConanMetadataType: reflect.TypeOf(ConanMetadata{}),
|
||||||
@ -83,5 +83,8 @@ func CleanMetadataType(typ MetadataType) MetadataType {
|
|||||||
if typ == "RpmdbMetadata" {
|
if typ == "RpmdbMetadata" {
|
||||||
return RpmMetadataType
|
return RpmMetadataType
|
||||||
}
|
}
|
||||||
|
if typ == "GolangBinMetadata" {
|
||||||
|
return GolangMetadataType
|
||||||
|
}
|
||||||
return typ
|
return typ
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user