mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 16:33:21 +01:00
fix: duplicate entries in cyclonedx dependency list (#2063)
Signed-off-by: Keith Zantow <kzantow@gmail.com>
This commit is contained in:
parent
d08e2be768
commit
4ae94c37eb
@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/CycloneDX/cyclonedx-go"
|
||||
"github.com/google/uuid"
|
||||
"golang.org/x/exp/slices"
|
||||
|
||||
"github.com/anchore/syft/internal"
|
||||
"github.com/anchore/syft/internal/log"
|
||||
@ -139,7 +140,7 @@ func isExpressiblePackageRelationship(ty artifact.RelationshipType) bool {
|
||||
}
|
||||
|
||||
func toDependencies(relationships []artifact.Relationship) []cyclonedx.Dependency {
|
||||
result := make([]cyclonedx.Dependency, 0)
|
||||
dependencies := map[string]*cyclonedx.Dependency{}
|
||||
for _, r := range relationships {
|
||||
exists := isExpressiblePackageRelationship(r.Type)
|
||||
if !exists {
|
||||
@ -160,15 +161,32 @@ func toDependencies(relationships []artifact.Relationship) []cyclonedx.Dependenc
|
||||
continue
|
||||
}
|
||||
|
||||
// ind dep
|
||||
|
||||
innerDeps := []string{}
|
||||
innerDeps = append(innerDeps, deriveBomRef(fromPkg))
|
||||
result = append(result, cyclonedx.Dependency{
|
||||
Ref: deriveBomRef(toPkg),
|
||||
Dependencies: &innerDeps,
|
||||
})
|
||||
toRef := deriveBomRef(toPkg)
|
||||
dep := dependencies[toRef]
|
||||
if dep == nil {
|
||||
dep = &cyclonedx.Dependency{
|
||||
Ref: toRef,
|
||||
Dependencies: &[]string{},
|
||||
}
|
||||
dependencies[toRef] = dep
|
||||
}
|
||||
|
||||
fromRef := deriveBomRef(fromPkg)
|
||||
if !slices.Contains(*dep.Dependencies, fromRef) {
|
||||
*dep.Dependencies = append(*dep.Dependencies, fromRef)
|
||||
}
|
||||
}
|
||||
|
||||
result := make([]cyclonedx.Dependency, 0, len(dependencies))
|
||||
for _, dep := range dependencies {
|
||||
slices.Sort(*dep.Dependencies)
|
||||
result = append(result, *dep)
|
||||
}
|
||||
|
||||
slices.SortFunc(result, func(a, b cyclonedx.Dependency) bool {
|
||||
return a.Ref < b.Ref
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package cyclonedxhelpers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/CycloneDX/cyclonedx-go"
|
||||
@ -43,28 +44,34 @@ func Test_relationships(t *testing.T) {
|
||||
p1 := pkg.Package{
|
||||
Name: "p1",
|
||||
}
|
||||
p1.SetID()
|
||||
|
||||
p2 := pkg.Package{
|
||||
Name: "p2",
|
||||
}
|
||||
p2.SetID()
|
||||
|
||||
p3 := pkg.Package{
|
||||
Name: "p3",
|
||||
}
|
||||
p3.SetID()
|
||||
|
||||
p4 := pkg.Package{
|
||||
Name: "p4",
|
||||
}
|
||||
|
||||
for _, p := range []*pkg.Package{&p1, &p2, &p3, &p4} {
|
||||
p.PURL = fmt.Sprintf("pkg:generic/%s@%s", p.Name, p.Name)
|
||||
p.SetID()
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
sbom sbom.SBOM
|
||||
expected []string
|
||||
expected *[]cyclonedx.Dependency
|
||||
}{
|
||||
{
|
||||
name: "package dependencyOf relationships output as dependencies",
|
||||
sbom: sbom.SBOM{
|
||||
Artifacts: sbom.Artifacts{
|
||||
Packages: pkg.NewCollection(p1, p2, p3),
|
||||
Packages: pkg.NewCollection(p1, p2, p3, p4),
|
||||
},
|
||||
Relationships: []artifact.Relationship{
|
||||
{
|
||||
@ -77,9 +84,28 @@ func Test_relationships(t *testing.T) {
|
||||
To: p1,
|
||||
Type: artifact.DependencyOfRelationship,
|
||||
},
|
||||
{
|
||||
From: p4,
|
||||
To: p2,
|
||||
Type: artifact.DependencyOfRelationship,
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &[]cyclonedx.Dependency{
|
||||
{
|
||||
Ref: deriveBomRef(p1),
|
||||
Dependencies: &[]string{
|
||||
deriveBomRef(p2),
|
||||
deriveBomRef(p3),
|
||||
},
|
||||
},
|
||||
{
|
||||
Ref: deriveBomRef(p2),
|
||||
Dependencies: &[]string{
|
||||
deriveBomRef(p4),
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: []string{p2.Name, p3.Name},
|
||||
},
|
||||
{
|
||||
name: "package contains relationships not output",
|
||||
@ -108,28 +134,7 @@ func Test_relationships(t *testing.T) {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
cdx := ToFormatModel(test.sbom)
|
||||
got := cdx.Dependencies
|
||||
|
||||
var deps []string
|
||||
if got != nil {
|
||||
for _, r := range *got {
|
||||
for _, d := range *r.Dependencies {
|
||||
c := findComponent(cdx, d)
|
||||
require.NotNil(t, c)
|
||||
deps = append(deps, c.Name)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
require.Equal(t, test.expected, deps)
|
||||
require.Equal(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func findComponent(cdx *cyclonedx.BOM, bomRef string) *cyclonedx.Component {
|
||||
for _, c := range *cdx.Components {
|
||||
if c.BOMRef == bomRef {
|
||||
return &c
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user