From 82eafeaf4a3df6dbea50dcc154954dda410068ad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Aug 2023 17:22:51 -0400 Subject: [PATCH] chore(deps): bump github.com/vifraa/gopom from 0.2.2 to 1.0.0 (#2008) * chore(deps): bump github.com/vifraa/gopom from 0.2.2 to 1.0.0 * refactor: update consumer code to use new optional values Bumps [github.com/vifraa/gopom](https://github.com/vifraa/gopom) from 0.2.2 to 1.0.0. - [Release notes](https://github.com/vifraa/gopom/releases) - [Commits](https://github.com/vifraa/gopom/compare/v0.2.2...v1.0.0) --- updated-dependencies: - dependency-name: github.com/vifraa/gopom dependency-type: direct:production update-type: version-update:semver-major ... --------- Signed-off-by: dependabot[bot] Signed-off-by: Christopher Phillips Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Christopher Phillips --- go.mod | 2 +- go.sum | 4 +- syft/pkg/cataloger/java/parse_pom_xml.go | 94 +++++++++++++------ syft/pkg/cataloger/java/parse_pom_xml_test.go | 41 ++++---- 4 files changed, 95 insertions(+), 46 deletions(-) diff --git a/go.mod b/go.mod index 76a4b2196c2..c67d868d2e5 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.16.0 github.com/stretchr/testify v1.8.4 - github.com/vifraa/gopom v0.2.2 + github.com/vifraa/gopom v1.0.0 github.com/wagoodman/go-partybus v0.0.0-20230516145632-8ccac152c651 github.com/wagoodman/go-progress v0.0.0-20230301185719-21920a456ad5 github.com/xeipuuv/gojsonschema v1.2.0 diff --git a/go.sum b/go.sum index 25f2fb02c23..7ae75b12f7d 100644 --- a/go.sum +++ b/go.sum @@ -687,8 +687,8 @@ github.com/vbatts/go-mtree v0.5.3 h1:S/jYlfG8rZ+a0bhZd+RANXejy7M4Js8fq9U+XoWTd5w github.com/vbatts/go-mtree v0.5.3/go.mod h1:eXsdoPMdL2jcJx6HweWi9lYQxBsTp4lNhqqAjgkZUg8= github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck= github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY= -github.com/vifraa/gopom v0.2.2 h1:zrqoCUVIplcsETouv3xxHPvfI/WV1GUPrdX2+Diahzo= -github.com/vifraa/gopom v0.2.2/go.mod h1:oPa1dcrGrtlO37WPDBm5SqHAT+wTgF8An1Q71Z6Vv4o= +github.com/vifraa/gopom v1.0.0 h1:L9XlKbyvid8PAIK8nr0lihMApJQg/12OBvMA28BcWh0= +github.com/vifraa/gopom v1.0.0/go.mod h1:oPa1dcrGrtlO37WPDBm5SqHAT+wTgF8An1Q71Z6Vv4o= github.com/wagoodman/go-partybus v0.0.0-20230516145632-8ccac152c651 h1:jIVmlAFIqV3d+DOxazTR9v+zgj8+VYuQBzPgBZvWBHA= github.com/wagoodman/go-partybus v0.0.0-20230516145632-8ccac152c651/go.mod h1:b26F2tHLqaoRQf8DywqzVaV1MQ9yvjb0OMcNl7Nxu20= github.com/wagoodman/go-progress v0.0.0-20230301185719-21920a456ad5 h1:lwgTsTy18nYqASnH58qyfRW/ldj7Gt2zzBvgYPzdA4s= diff --git a/syft/pkg/cataloger/java/parse_pom_xml.go b/syft/pkg/cataloger/java/parse_pom_xml.go index ed2a3c9efb4..704cb559808 100644 --- a/syft/pkg/cataloger/java/parse_pom_xml.go +++ b/syft/pkg/cataloger/java/parse_pom_xml.go @@ -28,17 +28,19 @@ func parserPomXML(_ file.Resolver, _ *generic.Environment, reader file.LocationR } var pkgs []pkg.Package - for _, dep := range pom.Dependencies { - p := newPackageFromPom( - pom, - dep, - reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), - ) - if p.Name == "" { - continue - } + if pom.Dependencies != nil { + for _, dep := range *pom.Dependencies { + p := newPackageFromPom( + pom, + dep, + reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), + ) + if p.Name == "" { + continue + } - pkgs = append(pkgs, p) + pkgs = append(pkgs, p) + } } return pkgs, nil, nil @@ -53,15 +55,18 @@ func parsePomXMLProject(path string, reader io.Reader) (*pkg.PomProject, error) } func newPomProject(path string, p gopom.Project) *pkg.PomProject { + artifactID := safeString(p.ArtifactID) + name := safeString(p.Name) + projectURL := safeString(p.URL) return &pkg.PomProject{ Path: path, Parent: pomParent(p, p.Parent), GroupID: resolveProperty(p, p.GroupID), - ArtifactID: p.ArtifactID, + ArtifactID: artifactID, Version: resolveProperty(p, p.Version), - Name: p.Name, + Name: name, Description: cleanDescription(p.Description), - URL: p.URL, + URL: projectURL, } } @@ -74,7 +79,7 @@ func newPackageFromPom(pom gopom.Project, dep gopom.Dependency, locations ...fil }, } - name := dep.ArtifactID + name := safeString(dep.ArtifactID) version := resolveProperty(pom, dep.Version) p := pkg.Package{ @@ -104,19 +109,29 @@ func decodePomXML(content io.Reader) (project gopom.Project, err error) { return project, nil } -func pomParent(pom gopom.Project, parent gopom.Parent) (result *pkg.PomParent) { - if parent.ArtifactID != "" || parent.GroupID != "" || parent.Version != "" { - result = &pkg.PomParent{ - GroupID: resolveProperty(pom, parent.GroupID), - ArtifactID: parent.ArtifactID, - Version: resolveProperty(pom, parent.Version), - } +func pomParent(pom gopom.Project, parent *gopom.Parent) (result *pkg.PomParent) { + if parent == nil { + return nil + } + + artifactID := safeString(parent.ArtifactID) + result = &pkg.PomParent{ + GroupID: resolveProperty(pom, parent.GroupID), + ArtifactID: artifactID, + Version: resolveProperty(pom, parent.Version), + } + + if result.GroupID == "" && result.ArtifactID == "" && result.Version == "" { + return nil } return result } -func cleanDescription(original string) (cleaned string) { - descriptionLines := strings.Split(original, "\n") +func cleanDescription(original *string) (cleaned string) { + if original == nil { + return "" + } + descriptionLines := strings.Split(*original, "\n") for _, line := range descriptionLines { line = strings.TrimSpace(line) if len(line) == 0 { @@ -130,12 +145,17 @@ func cleanDescription(original string) (cleaned string) { // resolveProperty emulates some maven property resolution logic by looking in the project's variables // as well as supporting the project expressions like ${project.parent.groupId}. // If no match is found, the entire expression including ${} is returned -func resolveProperty(pom gopom.Project, property string) string { - return propertyMatcher.ReplaceAllStringFunc(property, func(match string) string { +// +//nolint:gocognit +func resolveProperty(pom gopom.Project, property *string) string { + propertyCase := safeString(property) + return propertyMatcher.ReplaceAllStringFunc(propertyCase, func(match string) string { propertyName := strings.TrimSpace(match[2 : len(match)-1]) - if value, ok := pom.Properties.Entries[propertyName]; ok { + entries := pomProperties(pom) + if value, ok := entries[propertyName]; ok { return value } + // if we don't find anything directly in the pom properties, // see if we have a project.x expression and process this based // on the xml tags in gopom @@ -151,9 +171,15 @@ func resolveProperty(pom gopom.Project, property string) string { part := parts[partNum] for fieldNum := 0; fieldNum < pomValueType.NumField(); fieldNum++ { f := pomValueType.Field(fieldNum) - if part == f.Tag.Get("xml") { + tag := f.Tag.Get("xml") + tag = strings.TrimSuffix(tag, ",omitempty") + if part == tag { pomValue = pomValue.Field(fieldNum) pomValueType = pomValue.Type() + if pomValueType.Kind() == reflect.Ptr { + pomValue = pomValue.Elem() + pomValueType = pomValue.Type() + } if partNum == numParts-1 { return fmt.Sprintf("%v", pomValue.Interface()) } @@ -165,3 +191,17 @@ func resolveProperty(pom gopom.Project, property string) string { return match }) } + +func pomProperties(p gopom.Project) map[string]string { + if p.Properties != nil { + return p.Properties.Entries + } + return map[string]string{} +} + +func safeString(s *string) string { + if s == nil { + return "" + } + return *s +} diff --git a/syft/pkg/cataloger/java/parse_pom_xml_test.go b/syft/pkg/cataloger/java/parse_pom_xml_test.go index 38825aaf81c..edcf5414452 100644 --- a/syft/pkg/cataloger/java/parse_pom_xml_test.go +++ b/syft/pkg/cataloger/java/parse_pom_xml_test.go @@ -272,13 +272,13 @@ func Test_parsePomXMLProject(t *testing.T) { func Test_pomParent(t *testing.T) { tests := []struct { name string - input gopom.Parent + input *gopom.Parent expected *pkg.PomParent }{ { name: "only group ID", - input: gopom.Parent{ - GroupID: "org.something", + input: &gopom.Parent{ + GroupID: stringPointer("org.something"), }, expected: &pkg.PomParent{ GroupID: "org.something", @@ -286,8 +286,8 @@ func Test_pomParent(t *testing.T) { }, { name: "only artifact ID", - input: gopom.Parent{ - ArtifactID: "something", + input: &gopom.Parent{ + ArtifactID: stringPointer("something"), }, expected: &pkg.PomParent{ ArtifactID: "something", @@ -295,22 +295,27 @@ func Test_pomParent(t *testing.T) { }, { name: "only Version", - input: gopom.Parent{ - Version: "something", + input: &gopom.Parent{ + Version: stringPointer("something"), }, expected: &pkg.PomParent{ Version: "something", }, }, + { + name: "nil", + input: nil, + expected: nil, + }, { name: "empty", - input: gopom.Parent{}, + input: &gopom.Parent{}, expected: nil, }, { name: "unused field", - input: gopom.Parent{ - RelativePath: "something", + input: &gopom.Parent{ + RelativePath: stringPointer("something"), }, expected: nil, }, @@ -341,7 +346,7 @@ func Test_cleanDescription(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - assert.Equal(t, test.expected, cleanDescription(test.input)) + assert.Equal(t, test.expected, cleanDescription(stringPointer(test.input))) }) } } @@ -357,7 +362,7 @@ func Test_resolveProperty(t *testing.T) { name: "property", property: "${version.number}", pom: gopom.Project{ - Properties: gopom.Properties{ + Properties: &gopom.Properties{ Entries: map[string]string{ "version.number": "12.5.0", }, @@ -369,7 +374,7 @@ func Test_resolveProperty(t *testing.T) { name: "groupId", property: "${project.groupId}", pom: gopom.Project{ - GroupID: "org.some.group", + GroupID: stringPointer("org.some.group"), }, expected: "org.some.group", }, @@ -377,8 +382,8 @@ func Test_resolveProperty(t *testing.T) { name: "parent groupId", property: "${project.parent.groupId}", pom: gopom.Project{ - Parent: gopom.Parent{ - GroupID: "org.some.parent", + Parent: &gopom.Parent{ + GroupID: stringPointer("org.some.parent"), }, }, expected: "org.some.parent", @@ -387,8 +392,12 @@ func Test_resolveProperty(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - resolved := resolveProperty(test.pom, test.property) + resolved := resolveProperty(test.pom, stringPointer(test.property)) assert.Equal(t, test.expected, resolved) }) } } + +func stringPointer(s string) *string { + return &s +}