diff --git a/syft/pkg/cataloger/java/maven_repo_utils.go b/syft/pkg/cataloger/java/maven_repo_utils.go index 603c63e83..126037c26 100644 --- a/syft/pkg/cataloger/java/maven_repo_utils.go +++ b/syft/pkg/cataloger/java/maven_repo_utils.go @@ -27,6 +27,33 @@ func formatMavenPomURL(groupID, artifactID, version, mavenBaseURL string) (reque return requestURL, err } +// An artifact can have its version defined in a parent's DependencyManagement section +func recursivelyFindVersionFromParentPom(groupID, artifactID, parentGroupID, parentArtifactID, parentVersion string, cfg ArchiveCatalogerConfig) string { + // As there can be nested parent poms, we'll recursively check for the version until we reach the max depth + for i := 0; i < cfg.MaxParentRecursiveDepth; i++ { + parentPom, err := getPomFromMavenRepo(parentGroupID, parentArtifactID, parentVersion, cfg.MavenBaseURL) + if err != nil { + // We don't want to abort here as the parent pom might not exist in Maven Central, we'll just log the error + log.Tracef("unable to get parent pom from Maven central: %v", err) + break + } + if parentPom != nil && parentPom.DependencyManagement != nil { + for _, dependency := range *parentPom.DependencyManagement.Dependencies { + if groupID == *dependency.GroupID && artifactID == *dependency.ArtifactID && dependency.Version != nil { + return *dependency.Version + } + } + } + if parentPom == nil || parentPom.Parent == nil { + break + } + parentGroupID = *parentPom.Parent.GroupID + parentArtifactID = *parentPom.Parent.ArtifactID + parentVersion = *parentPom.Parent.Version + } + return "" +} + func recursivelyFindLicensesFromParentPom(groupID, artifactID, version string, cfg ArchiveCatalogerConfig) []string { var licenses []string // As there can be nested parent poms, we'll recursively check for licenses until we reach the max depth diff --git a/syft/pkg/cataloger/java/parse_pom_xml.go b/syft/pkg/cataloger/java/parse_pom_xml.go index 7d6ce92b9..b3c6f2b6f 100644 --- a/syft/pkg/cataloger/java/parse_pom_xml.go +++ b/syft/pkg/cataloger/java/parse_pom_xml.go @@ -111,16 +111,22 @@ func newPackageFromPom(pom gopom.Project, dep gopom.Dependency, cfg ArchiveCatal version := resolveProperty(pom, dep.Version, "version") licenses := make([]pkg.License, 0) - if version != "" && cfg.UseNetwork { - parentLicenses := recursivelyFindLicensesFromParentPom( - m.PomProperties.GroupID, - m.PomProperties.ArtifactID, - version, - cfg) + if cfg.UseNetwork { + if version == "" { + // If we have no version then let's try to get it from a parent pom DependencyManagement section + version = recursivelyFindVersionFromParentPom(*dep.GroupID, *dep.ArtifactID, *pom.Parent.GroupID, *pom.Parent.ArtifactID, *pom.Parent.Version, cfg) + } + if version != "" { + parentLicenses := recursivelyFindLicensesFromParentPom( + m.PomProperties.GroupID, + m.PomProperties.ArtifactID, + version, + cfg) - if len(parentLicenses) > 0 { - for _, licenseName := range parentLicenses { - licenses = append(licenses, pkg.NewLicenseFromFields(licenseName, "", nil)) + if len(parentLicenses) > 0 { + for _, licenseName := range parentLicenses { + licenses = append(licenses, pkg.NewLicenseFromFields(licenseName, "", nil)) + } } } }