Skip to content

Commit 81b872b

Browse files
Merge pull request #393 from interlynk-io/392-if-there-is-no-url-in-the-metadata-supplier-a-parsing-error-occurs
Fix cyclonedx supplier and manufacture crash
2 parents 79c72a6 + 7ed0ab2 commit 81b872b

File tree

4 files changed

+59
-94
lines changed

4 files changed

+59
-94
lines changed

.tool-versions

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
golang 1.23.1
1+
golang 1.23.6

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ require (
1616
github.com/package-url/packageurl-go v0.1.3
1717
github.com/samber/lo v1.49.1
1818
github.com/spdx/tools-golang v0.5.5
19-
github.com/spf13/cobra v1.8.1
19+
github.com/spf13/cobra v1.9.1
2020
github.com/stretchr/testify v1.10.0
2121
go.uber.org/zap v1.27.0
2222
gopkg.in/yaml.v2 v2.4.0

go.sum

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ github.com/containerd/containerd v1.7.3 h1:cKwYKkP1eTj54bP3wCdXXBymmKRQMrWjkLSWZ
2727
github.com/containerd/containerd v1.7.3/go.mod h1:32FOM4/O0RkNg7AjQj3hDzN9cUGtu+HMvaKUNiqCZB8=
2828
github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E=
2929
github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
30-
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
30+
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
3131
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3232
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
3333
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -119,9 +119,8 @@ github.com/spdx/tools-golang v0.5.5 h1:61c0KLfAcNqAjlg6UNMdkwpMernhw3zVRwDZ2x9XO
119119
github.com/spdx/tools-golang v0.5.5/go.mod h1:MVIsXx8ZZzaRWNQpUDhC4Dud34edUYJYecciXgrw5vE=
120120
github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs=
121121
github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=
122-
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
123-
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
124-
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
122+
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
123+
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
125124
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
126125
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
127126
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=

pkg/sbom/cdx.go

Lines changed: 54 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -658,55 +658,64 @@ func (c *CdxDoc) parseAuthors() {
658658
}
659659

660660
func (c *CdxDoc) parseSupplier() {
661-
if c.doc.Metadata == nil {
661+
// Early return if required nested fields are nil
662+
if c.doc.Metadata == nil || c.doc.Metadata.Supplier == nil {
662663
return
663664
}
664665

665-
if c.doc.Metadata.Supplier == nil {
666-
return
666+
// Initialize supplier with known fields
667+
supplier := Supplier{
668+
Name: c.doc.Metadata.Supplier.Name,
667669
}
668670

669-
supplier := Supplier{}
670-
671-
supplier.Name = c.doc.Metadata.Supplier.Name
672-
supplier.URL = lo.FromPtr(c.doc.Metadata.Supplier.URL)[0]
671+
// Safely handle URL
672+
if urls := lo.FromPtr(c.doc.Metadata.Supplier.URL); len(urls) > 0 {
673+
supplier.URL = urls[0]
674+
}
673675

676+
// Handle contacts array
674677
if c.doc.Metadata.Supplier.Contact != nil {
675-
for _, cydxContact := range lo.FromPtr(c.doc.Metadata.Supplier.Contact) {
676-
ctt := Contact{}
677-
ctt.Name = cydxContact.Name
678-
ctt.Email = cydxContact.Email
679-
supplier.Contacts = append(supplier.Contacts, ctt)
678+
contacts := lo.FromPtr(c.doc.Metadata.Supplier.Contact)
679+
if len(contacts) > 0 {
680+
// Pre-allocate contacts slice with known capacity
681+
supplier.Contacts = make([]Contact, 0, len(contacts))
682+
683+
// Process each contact
684+
for _, cydxContact := range contacts {
685+
supplier.Contacts = append(supplier.Contacts, Contact{
686+
Name: cydxContact.Name,
687+
Email: cydxContact.Email,
688+
})
689+
}
680690
}
681691
}
682692

683693
c.CdxSupplier = supplier
684694
}
685695

686696
func (c *CdxDoc) parseManufacturer() {
687-
if c.doc.Metadata == nil {
697+
if c.doc.Metadata == nil || c.doc.Metadata.Manufacture == nil {
688698
return
689699
}
690700

691-
if c.doc.Metadata.Manufacture == nil {
692-
return
693-
}
694-
695-
m := Manufacturer{}
701+
manufacturer := Manufacturer{Name: c.doc.Metadata.Manufacture.Name}
696702

697-
m.Name = c.doc.Metadata.Manufacture.Name
698-
m.URL = lo.FromPtr(c.doc.Metadata.Manufacture.URL)[0]
703+
if urls := lo.FromPtr(c.doc.Metadata.Manufacture.URL); len(urls) > 0 {
704+
manufacturer.URL = urls[0]
705+
}
699706

700-
if c.doc.Metadata.Manufacture.Contact != nil {
701-
for _, cydxContact := range lo.FromPtr(c.doc.Metadata.Manufacture.Contact) {
702-
ctt := Contact{}
703-
ctt.Name = cydxContact.Name
704-
ctt.Email = cydxContact.Email
705-
m.Contacts = append(m.Contacts, ctt)
707+
contacts := lo.FromPtr(c.doc.Metadata.Manufacture.Contact)
708+
if len(contacts) > 0 {
709+
manufacturer.Contacts = make([]Contact, len(contacts))
710+
for i, contact := range contacts {
711+
manufacturer.Contacts[i] = Contact{
712+
Name: contact.Name,
713+
Email: contact.Email,
714+
}
706715
}
707716
}
708717

709-
c.CdxManufacturer = m
718+
c.CdxManufacturer = manufacturer
710719
}
711720

712721
func (c *CdxDoc) parsePrimaryCompAndRelationships() {
@@ -746,90 +755,47 @@ func (c *CdxDoc) parsePrimaryCompAndRelationships() {
746755
c.PrimaryComponent.Dependecies = totalDependencies
747756
}
748757

749-
// nolint
750-
func (c *CdxDoc) parseComposition() {
751-
if c.doc.Metadata == nil {
752-
return
753-
}
754-
if c.doc.Compositions == nil {
755-
return
756-
}
757-
c.composition = make(map[string]string)
758-
759-
for _, cp := range lo.FromPtr(c.doc.Compositions) {
760-
state := compNormalise(cp.BOMRef)
761-
c.composition[cp.BOMRef] = state
762-
}
763-
}
764-
765-
// nolint
766-
func compNormalise(compID string) string {
767-
switch cydx.CompositionAggregate(compID) {
768-
case cydx.CompositionAggregateComplete:
769-
return "complete"
770-
case cydx.CompositionAggregateIncomplete:
771-
return "incomplete"
772-
case cydx.CompositionAggregateIncompleteFirstPartyOnly:
773-
return "incomplete-first-party-only"
774-
case cydx.CompositionAggregateIncompleteFirstPartyOpenSourceOnly:
775-
return "incomplete-first-party-open-source-only"
776-
case cydx.CompositionAggregateIncompleteFirstPartyProprietaryOnly:
777-
return "incomplete-first-party-proprietary-only"
778-
case cydx.CompositionAggregateIncompleteThirdPartyOnly:
779-
return "incomplete-third-party-only"
780-
case cydx.CompositionAggregateIncompleteThirdPartyOpenSourceOnly:
781-
return "incomplete-third-party-open-source-only"
782-
case cydx.CompositionAggregateIncompleteThirdPartyProprietaryOnly:
783-
return "incomplete-third-party-proprietary-only"
784-
case cydx.CompositionAggregateNotSpecified:
785-
return "not-specified"
786-
case cydx.CompositionAggregateUnknown:
787-
return "unknown"
788-
}
789-
return "not-specified"
790-
}
791-
792758
func (c *CdxDoc) assignSupplier(comp *cydx.Component) *Supplier {
793759
if comp.Supplier == nil {
794760
c.addToLogs(fmt.Sprintf("cdx doc comp %s no supplier found", comp.Name))
795761
return nil
796762
}
797763

798-
supplier := Supplier{}
799-
800-
if comp.Supplier.Name != "" {
801-
supplier.Name = comp.Supplier.Name
802-
}
764+
supplier := Supplier{Name: comp.Supplier.Name}
803765

804-
if comp.Supplier.URL != nil && len(lo.FromPtr(comp.Supplier.URL)) > 0 {
805-
supplier.URL = lo.FromPtr(comp.Supplier.URL)[0]
766+
if urls := lo.FromPtr(comp.Supplier.URL); len(urls) > 0 {
767+
supplier.URL = urls[0]
806768
}
807769

808-
if comp.Supplier.Contact != nil {
809-
for _, cydxContact := range lo.FromPtr(comp.Supplier.Contact) {
810-
ctt := Contact{}
811-
ctt.Name = cydxContact.Name
812-
ctt.Email = cydxContact.Email
813-
supplier.Contacts = append(supplier.Contacts, ctt)
770+
contacts := lo.FromPtr(comp.Supplier.Contact)
771+
if len(contacts) > 0 {
772+
supplier.Contacts = make([]Contact, len(contacts))
773+
for i, contact := range contacts {
774+
supplier.Contacts[i] = Contact{
775+
Name: contact.Name,
776+
Email: contact.Email,
777+
}
814778
}
815779
}
816780

817781
return &supplier
818782
}
819783

820784
func (c *CdxDoc) parseCompositions() {
785+
c.compositions = make(map[string]string)
786+
821787
if c.doc.Compositions == nil {
822-
c.compositions = map[string]string{}
823788
return
824789
}
825790

826-
for _, comp := range lo.FromPtr(c.doc.Compositions) {
827-
if comp.Assemblies == nil {
791+
for _, composition := range lo.FromPtr(c.doc.Compositions) {
792+
assemblies := lo.FromPtr(composition.Assemblies)
793+
if len(assemblies) == 0 {
828794
continue
829795
}
830796

831-
for _, assembly := range lo.FromPtr(comp.Assemblies) {
832-
c.compositions[string(assembly)] = string(comp.Aggregate)
797+
for _, assembly := range assemblies {
798+
c.compositions[string(assembly)] = string(composition.Aggregate)
833799
}
834800
}
835801
}

0 commit comments

Comments
 (0)