diff --git a/syft/cataloger/java/archive_parser.go b/syft/cataloger/java/archive_parser.go index b25772304..7b103e9b8 100644 --- a/syft/cataloger/java/archive_parser.go +++ b/syft/cataloger/java/archive_parser.go @@ -178,36 +178,40 @@ func (j *archiveParser) discoverPkgsFromPomProperties(parentPkg *pkg.Package) ([ return nil, fmt.Errorf("failed to parse pom.properties (%s): %w", j.virtualPath, err) } - if propsObj != nil { - if propsObj.Version != "" && propsObj.ArtifactID != "" { - // TODO: if there is no parentPkg (no java manifest) one of these poms could be the parent. We should discover the right parent and attach the correct info accordingly to each discovered package + if propsObj == nil { + continue + } - // keep the artifact name within the virtual path if this package does not match the parent package - vPathSuffix := "" - if !strings.HasPrefix(propsObj.ArtifactID, parentPkg.Name) { - vPathSuffix += ":" + propsObj.ArtifactID - } - virtualPath := j.virtualPath + vPathSuffix + if propsObj.Version != "" && propsObj.ArtifactID != "" { + // TODO: if there is no parentPkg (no java manifest) one of these poms could be the parent. We should discover the right parent and attach the correct info accordingly to each discovered package - // discovered props = new package - p := pkg.Package{ - Name: propsObj.ArtifactID, - Version: propsObj.Version, - Language: pkg.Java, - Type: pkg.JavaPkg, - MetadataType: pkg.JavaMetadataType, - Metadata: pkg.JavaMetadata{ - VirtualPath: virtualPath, - PomProperties: propsObj, - Parent: parentPkg, - }, - } + // keep the artifact name within the virtual path if this package does not match the parent package + vPathSuffix := "" + if parentPkg != nil && !strings.HasPrefix(propsObj.ArtifactID, parentPkg.Name) { + vPathSuffix += ":" + propsObj.ArtifactID + } + virtualPath := j.virtualPath + vPathSuffix - pkgKey := uniquePkgKey(&p) + // discovered props = new package + p := pkg.Package{ + Name: propsObj.ArtifactID, + Version: propsObj.Version, + Language: pkg.Java, + Type: pkg.JavaPkg, + MetadataType: pkg.JavaMetadataType, + Metadata: pkg.JavaMetadata{ + VirtualPath: virtualPath, + PomProperties: propsObj, + Parent: parentPkg, + }, + } - // the name/version pair matches... - matchesParentPkg := pkgKey == parentKey + pkgKey := uniquePkgKey(&p) + // the name/version pair matches... + matchesParentPkg := pkgKey == parentKey + + if parentPkg != nil { // the virtual path matches... matchesParentPkg = matchesParentPkg || parentPkg.Metadata.(pkg.JavaMetadata).VirtualPath == virtualPath @@ -231,11 +235,13 @@ func (j *archiveParser) discoverPkgsFromPomProperties(parentPkg *pkg.Package) ([ parentMetadata.PomProperties = propsObj parentPkg.Metadata = parentMetadata } - } else if !j.discoveredPkgs.Contains(pkgKey) { - // only keep packages we haven't seen yet (and are not related to the parent package) - pkgs = append(pkgs, p) } } + + if !matchesParentPkg && !j.discoveredPkgs.Contains(pkgKey) { + // only keep packages we haven't seen yet (and are not related to the parent package) + pkgs = append(pkgs, p) + } } } return pkgs, nil diff --git a/test/integration/java_no_main_package_test.go b/test/integration/java_no_main_package_test.go new file mode 100644 index 000000000..e330a78fb --- /dev/null +++ b/test/integration/java_no_main_package_test.go @@ -0,0 +1,20 @@ +package integration + +import ( + "github.com/anchore/stereoscope/pkg/imagetest" + "github.com/anchore/syft/syft" + "github.com/anchore/syft/syft/source" + "testing" +) + +func TestJavaNoMainPackage(t *testing.T) { // Regression: https://github.com/anchore/syft/issues/252 + fixtureImageName := "image-java-no-main-package" + _, cleanup := imagetest.GetFixtureImage(t, "docker-archive", fixtureImageName) + tarPath := imagetest.GetFixtureImageTarPath(t, fixtureImageName) + defer cleanup() + + _, _, _, err := syft.Catalog("docker-archive:"+tarPath, source.SquashedScope) + if err != nil { + t.Fatalf("failed to catalog image: %+v", err) + } +} diff --git a/test/integration/test-fixtures/image-java-no-main-package/Dockerfile b/test/integration/test-fixtures/image-java-no-main-package/Dockerfile new file mode 100644 index 000000000..c6100ae44 --- /dev/null +++ b/test/integration/test-fixtures/image-java-no-main-package/Dockerfile @@ -0,0 +1,23 @@ +FROM jenkins:2.60.3 + +USER root + +WORKDIR /usr/share/jenkins + +RUN mkdir tmp + +WORKDIR /usr/share/jenkins/tmp + +RUN apt-get update 2>&1 > /dev/null && apt-get install -y less zip 2>&1 > /dev/null + +RUN unzip ../jenkins.war 2>&1 > /dev/null + +RUN rm -f ./META-INF/MANIFEST.MF + +WORKDIR /usr/share/jenkins + +RUN rm -rf jenkins.war + +RUN cd ./tmp && zip -r ../jenkins.war . && cd .. + +RUN rm -rf ./tmp diff --git a/test/integration/test-fixtures/image-large-apk-data/Dockerfile b/test/integration/test-fixtures/image-large-apk-data/Dockerfile index 357f0a5d9..98ccb7373 100644 --- a/test/integration/test-fixtures/image-large-apk-data/Dockerfile +++ b/test/integration/test-fixtures/image-large-apk-data/Dockerfile @@ -1,5 +1,5 @@ FROM alpine@sha256:d9a7354e3845ea8466bb00b22224d9116b183e594527fb5b6c3d30bc01a20378 RUN apk add --no-cache \ - tzdata=2020f-r0 \ + tzdata=2021a-r0 \ vim=8.2.2320-r0 \ alpine-sdk=1.0-r0