Skip to content

Commit

Permalink
Merge pull request #393 from interlynk-io/392-if-there-is-no-url-in-t…
Browse files Browse the repository at this point in the history
…he-metadata-supplier-a-parsing-error-occurs

Fix cyclonedx supplier and manufacture crash
  • Loading branch information
riteshnoronha authored Feb 19, 2025
2 parents 79c72a6 + 7ed0ab2 commit 81b872b
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 94 deletions.
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1 +1 @@
golang 1.23.1
golang 1.23.6
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ require (
github.com/package-url/packageurl-go v0.1.3
github.com/samber/lo v1.49.1
github.com/spdx/tools-golang v0.5.5
github.com/spf13/cobra v1.8.1
github.com/spf13/cobra v1.9.1
github.com/stretchr/testify v1.10.0
go.uber.org/zap v1.27.0
gopkg.in/yaml.v2 v2.4.0
Expand Down
7 changes: 3 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ github.com/containerd/containerd v1.7.3 h1:cKwYKkP1eTj54bP3wCdXXBymmKRQMrWjkLSWZ
github.com/containerd/containerd v1.7.3/go.mod h1:32FOM4/O0RkNg7AjQj3hDzN9cUGtu+HMvaKUNiqCZB8=
github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E=
github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down Expand Up @@ -119,9 +119,8 @@ github.com/spdx/tools-golang v0.5.5 h1:61c0KLfAcNqAjlg6UNMdkwpMernhw3zVRwDZ2x9XO
github.com/spdx/tools-golang v0.5.5/go.mod h1:MVIsXx8ZZzaRWNQpUDhC4Dud34edUYJYecciXgrw5vE=
github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs=
github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand Down
142 changes: 54 additions & 88 deletions pkg/sbom/cdx.go
Original file line number Diff line number Diff line change
Expand Up @@ -658,55 +658,64 @@ func (c *CdxDoc) parseAuthors() {
}

func (c *CdxDoc) parseSupplier() {
if c.doc.Metadata == nil {
// Early return if required nested fields are nil
if c.doc.Metadata == nil || c.doc.Metadata.Supplier == nil {
return
}

if c.doc.Metadata.Supplier == nil {
return
// Initialize supplier with known fields
supplier := Supplier{
Name: c.doc.Metadata.Supplier.Name,
}

supplier := Supplier{}

supplier.Name = c.doc.Metadata.Supplier.Name
supplier.URL = lo.FromPtr(c.doc.Metadata.Supplier.URL)[0]
// Safely handle URL
if urls := lo.FromPtr(c.doc.Metadata.Supplier.URL); len(urls) > 0 {
supplier.URL = urls[0]
}

// Handle contacts array
if c.doc.Metadata.Supplier.Contact != nil {
for _, cydxContact := range lo.FromPtr(c.doc.Metadata.Supplier.Contact) {
ctt := Contact{}
ctt.Name = cydxContact.Name
ctt.Email = cydxContact.Email
supplier.Contacts = append(supplier.Contacts, ctt)
contacts := lo.FromPtr(c.doc.Metadata.Supplier.Contact)
if len(contacts) > 0 {
// Pre-allocate contacts slice with known capacity
supplier.Contacts = make([]Contact, 0, len(contacts))

// Process each contact
for _, cydxContact := range contacts {
supplier.Contacts = append(supplier.Contacts, Contact{
Name: cydxContact.Name,
Email: cydxContact.Email,
})
}
}
}

c.CdxSupplier = supplier
}

func (c *CdxDoc) parseManufacturer() {
if c.doc.Metadata == nil {
if c.doc.Metadata == nil || c.doc.Metadata.Manufacture == nil {
return
}

if c.doc.Metadata.Manufacture == nil {
return
}

m := Manufacturer{}
manufacturer := Manufacturer{Name: c.doc.Metadata.Manufacture.Name}

m.Name = c.doc.Metadata.Manufacture.Name
m.URL = lo.FromPtr(c.doc.Metadata.Manufacture.URL)[0]
if urls := lo.FromPtr(c.doc.Metadata.Manufacture.URL); len(urls) > 0 {
manufacturer.URL = urls[0]
}

if c.doc.Metadata.Manufacture.Contact != nil {
for _, cydxContact := range lo.FromPtr(c.doc.Metadata.Manufacture.Contact) {
ctt := Contact{}
ctt.Name = cydxContact.Name
ctt.Email = cydxContact.Email
m.Contacts = append(m.Contacts, ctt)
contacts := lo.FromPtr(c.doc.Metadata.Manufacture.Contact)
if len(contacts) > 0 {
manufacturer.Contacts = make([]Contact, len(contacts))
for i, contact := range contacts {
manufacturer.Contacts[i] = Contact{
Name: contact.Name,
Email: contact.Email,
}
}
}

c.CdxManufacturer = m
c.CdxManufacturer = manufacturer
}

func (c *CdxDoc) parsePrimaryCompAndRelationships() {
Expand Down Expand Up @@ -746,90 +755,47 @@ func (c *CdxDoc) parsePrimaryCompAndRelationships() {
c.PrimaryComponent.Dependecies = totalDependencies
}

// nolint
func (c *CdxDoc) parseComposition() {
if c.doc.Metadata == nil {
return
}
if c.doc.Compositions == nil {
return
}
c.composition = make(map[string]string)

for _, cp := range lo.FromPtr(c.doc.Compositions) {
state := compNormalise(cp.BOMRef)
c.composition[cp.BOMRef] = state
}
}

// nolint
func compNormalise(compID string) string {
switch cydx.CompositionAggregate(compID) {
case cydx.CompositionAggregateComplete:
return "complete"
case cydx.CompositionAggregateIncomplete:
return "incomplete"
case cydx.CompositionAggregateIncompleteFirstPartyOnly:
return "incomplete-first-party-only"
case cydx.CompositionAggregateIncompleteFirstPartyOpenSourceOnly:
return "incomplete-first-party-open-source-only"
case cydx.CompositionAggregateIncompleteFirstPartyProprietaryOnly:
return "incomplete-first-party-proprietary-only"
case cydx.CompositionAggregateIncompleteThirdPartyOnly:
return "incomplete-third-party-only"
case cydx.CompositionAggregateIncompleteThirdPartyOpenSourceOnly:
return "incomplete-third-party-open-source-only"
case cydx.CompositionAggregateIncompleteThirdPartyProprietaryOnly:
return "incomplete-third-party-proprietary-only"
case cydx.CompositionAggregateNotSpecified:
return "not-specified"
case cydx.CompositionAggregateUnknown:
return "unknown"
}
return "not-specified"
}

func (c *CdxDoc) assignSupplier(comp *cydx.Component) *Supplier {
if comp.Supplier == nil {
c.addToLogs(fmt.Sprintf("cdx doc comp %s no supplier found", comp.Name))
return nil
}

supplier := Supplier{}

if comp.Supplier.Name != "" {
supplier.Name = comp.Supplier.Name
}
supplier := Supplier{Name: comp.Supplier.Name}

if comp.Supplier.URL != nil && len(lo.FromPtr(comp.Supplier.URL)) > 0 {
supplier.URL = lo.FromPtr(comp.Supplier.URL)[0]
if urls := lo.FromPtr(comp.Supplier.URL); len(urls) > 0 {
supplier.URL = urls[0]
}

if comp.Supplier.Contact != nil {
for _, cydxContact := range lo.FromPtr(comp.Supplier.Contact) {
ctt := Contact{}
ctt.Name = cydxContact.Name
ctt.Email = cydxContact.Email
supplier.Contacts = append(supplier.Contacts, ctt)
contacts := lo.FromPtr(comp.Supplier.Contact)
if len(contacts) > 0 {
supplier.Contacts = make([]Contact, len(contacts))
for i, contact := range contacts {
supplier.Contacts[i] = Contact{
Name: contact.Name,
Email: contact.Email,
}
}
}

return &supplier
}

func (c *CdxDoc) parseCompositions() {
c.compositions = make(map[string]string)

if c.doc.Compositions == nil {
c.compositions = map[string]string{}
return
}

for _, comp := range lo.FromPtr(c.doc.Compositions) {
if comp.Assemblies == nil {
for _, composition := range lo.FromPtr(c.doc.Compositions) {
assemblies := lo.FromPtr(composition.Assemblies)
if len(assemblies) == 0 {
continue
}

for _, assembly := range lo.FromPtr(comp.Assemblies) {
c.compositions[string(assembly)] = string(comp.Aggregate)
for _, assembly := range assemblies {
c.compositions[string(assembly)] = string(composition.Aggregate)
}
}
}

0 comments on commit 81b872b

Please sign in to comment.