mirror of
https://github.com/anchore/syft
synced 2024-09-20 14:11:54 +00:00
fix: syft does not handle the case of parsing a jar with multiple poms (#2231)
--------- Signed-off-by: Colm O hEigeartaigh <coheigea@apache.org> Signed-off-by: Christopher Phillips <christopher.phillips@anchore.com> Co-authored-by: Christopher Phillips <christopher.phillips@anchore.com>
This commit is contained in:
parent
dc9bc58480
commit
26cdbfc299
9 changed files with 346 additions and 11 deletions
|
@ -263,21 +263,21 @@ func (j *archiveParser) guessMainPackageNameAndVersionFromPomInfo() (name, versi
|
|||
pomMatches := j.fileManifest.GlobMatch(false, pomXMLGlob)
|
||||
var pomPropertiesObject pkg.JavaPomProperties
|
||||
var pomProjectObject *parsedPomProject
|
||||
if len(pomPropertyMatches) == 1 || len(pomMatches) == 1 {
|
||||
// we have exactly 1 pom.properties or pom.xml in the archive; assume it represents the
|
||||
// package we're scanning if the names seem like a plausible match
|
||||
properties, _ := pomPropertiesByParentPath(j.archivePath, j.location, pomPropertyMatches)
|
||||
projects, _ := pomProjectByParentPath(j.archivePath, j.location, pomMatches)
|
||||
|
||||
for parentPath, propertiesObj := range properties {
|
||||
if artifactIDMatchesFilename(propertiesObj.ArtifactID, j.fileInfo.name) {
|
||||
pomPropertiesObject = propertiesObj
|
||||
if proj, exists := projects[parentPath]; exists {
|
||||
pomProjectObject = proj
|
||||
}
|
||||
// Find the pom.properties/pom.xml if the names seem like a plausible match
|
||||
properties, _ := pomPropertiesByParentPath(j.archivePath, j.location, pomPropertyMatches)
|
||||
projects, _ := pomProjectByParentPath(j.archivePath, j.location, pomMatches)
|
||||
|
||||
for parentPath, propertiesObj := range properties {
|
||||
if artifactIDMatchesFilename(propertiesObj.ArtifactID, j.fileInfo.name) {
|
||||
pomPropertiesObject = propertiesObj
|
||||
if proj, exists := projects[parentPath]; exists {
|
||||
pomProjectObject = proj
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
name = pomPropertiesObject.ArtifactID
|
||||
if name == "" && pomProjectObject != nil {
|
||||
name = pomProjectObject.ArtifactID
|
||||
|
|
|
@ -1036,6 +1036,7 @@ func Test_parseJavaArchive_regressions(t *testing.T) {
|
|||
fixtureName string
|
||||
expectedPkgs []pkg.Package
|
||||
expectedRelationships []artifact.Relationship
|
||||
assignParent bool
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
|
@ -1146,10 +1147,74 @@ func Test_parseJavaArchive_regressions(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "multiple pom for parent selection regression (pr 2231)",
|
||||
fixtureName: "api-all-2.0.0-sources",
|
||||
assignParent: true,
|
||||
expectedPkgs: []pkg.Package{
|
||||
{
|
||||
Name: "api-all",
|
||||
Version: "2.0.0",
|
||||
Type: pkg.JavaPkg,
|
||||
Language: pkg.Java,
|
||||
PURL: "pkg:maven/org.apache.directory.api/api-all@2.0.0",
|
||||
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/jar-metadata/cache/api-all-2.0.0-sources.jar")),
|
||||
Metadata: pkg.JavaArchive{
|
||||
VirtualPath: "test-fixtures/jar-metadata/cache/api-all-2.0.0-sources.jar",
|
||||
Manifest: &pkg.JavaManifest{
|
||||
Main: map[string]string{
|
||||
"Build-Jdk": "1.8.0_191",
|
||||
"Built-By": "elecharny",
|
||||
"Created-By": "Apache Maven 3.6.0",
|
||||
"Manifest-Version": "1.0",
|
||||
},
|
||||
},
|
||||
PomProperties: &pkg.JavaPomProperties{
|
||||
Path: "META-INF/maven/org.apache.directory.api/api-all/pom.properties",
|
||||
GroupID: "org.apache.directory.api",
|
||||
ArtifactID: "api-all",
|
||||
Version: "2.0.0",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "api-asn1-api",
|
||||
Version: "2.0.0",
|
||||
PURL: "pkg:maven/org.apache.directory.api/api-asn1-api@2.0.0",
|
||||
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/jar-metadata/cache/api-all-2.0.0-sources.jar")),
|
||||
Type: pkg.JavaPkg,
|
||||
Language: pkg.Java,
|
||||
Metadata: pkg.JavaArchive{
|
||||
VirtualPath: "test-fixtures/jar-metadata/cache/api-all-2.0.0-sources.jar:org.apache.directory.api:api-asn1-api",
|
||||
PomProperties: &pkg.JavaPomProperties{
|
||||
Path: "META-INF/maven/org.apache.directory.api/api-asn1-api/pom.properties",
|
||||
GroupID: "org.apache.directory.api",
|
||||
ArtifactID: "api-asn1-api",
|
||||
Version: "2.0.0",
|
||||
},
|
||||
PomProject: &pkg.JavaPomProject{
|
||||
Path: "META-INF/maven/org.apache.directory.api/api-asn1-api/pom.xml",
|
||||
ArtifactID: "api-asn1-api",
|
||||
Name: "Apache Directory API ASN.1 API",
|
||||
Description: "ASN.1 API",
|
||||
Parent: &pkg.JavaPomParent{
|
||||
GroupID: "org.apache.directory.api",
|
||||
ArtifactID: "api-asn1-parent",
|
||||
Version: "2.0.0",
|
||||
},
|
||||
},
|
||||
Parent: nil,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
gap := newGenericArchiveParserAdapter(Config{})
|
||||
if tt.assignParent {
|
||||
assignParent(&tt.expectedPkgs[0], tt.expectedPkgs[1:]...)
|
||||
}
|
||||
pkgtest.NewCatalogTester().
|
||||
FromFile(t, generateJavaMetadataJarFixture(t, tt.fixtureName)).
|
||||
Expects(tt.expectedPkgs, tt.expectedRelationships).
|
||||
|
@ -1159,6 +1224,18 @@ func Test_parseJavaArchive_regressions(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func assignParent(parent *pkg.Package, childPackages ...pkg.Package) {
|
||||
for i, jp := range childPackages {
|
||||
if v, ok := jp.Metadata.(pkg.JavaArchive); ok {
|
||||
parent := *parent
|
||||
// PURL are not calculated after the fact for parent
|
||||
parent.PURL = ""
|
||||
v.Parent = &parent
|
||||
childPackages[i].Metadata = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func generateJavaMetadataJarFixture(t *testing.T, fixtureName string) string {
|
||||
fixturePath := filepath.Join("test-fixtures/jar-metadata/cache/", fixtureName+".jar")
|
||||
if _, err := os.Stat(fixturePath); !os.IsNotExist(err) {
|
||||
|
|
|
@ -3,6 +3,7 @@ CACHE_PATH = $(shell pwd)/cache
|
|||
|
||||
JACKSON_CORE = jackson-core-2.15.2
|
||||
SBT_JACKSON_CORE = com.fasterxml.jackson.core.jackson-core-2.15.2
|
||||
API_ALL_SOURCES = api-all-2.0.0-sources
|
||||
|
||||
$(CACHE_DIR):
|
||||
mkdir -p $(CACHE_DIR)
|
||||
|
@ -12,3 +13,6 @@ $(CACHE_DIR)/$(JACKSON_CORE).jar: $(CACHE_DIR)
|
|||
|
||||
$(CACHE_DIR)/$(SBT_JACKSON_CORE).jar: $(CACHE_DIR)
|
||||
cd $(SBT_JACKSON_CORE) && zip -r $(CACHE_PATH)/$(SBT_JACKSON_CORE).jar .
|
||||
|
||||
$(CACHE_DIR)/$(API_ALL_SOURCES).jar: $(CACHE_DIR)
|
||||
cd $(API_ALL_SOURCES) && zip -r $(CACHE_PATH)/$(API_ALL_SOURCES).jar .
|
|
@ -3,3 +3,11 @@
|
|||
Each directory is the name of a jar to be created (simply a zip) based on the contents of the directory.
|
||||
This prevents us from having to create real jars by hand or keep binaries in the repo. This also means we dont need the
|
||||
entire jar, only the necessary metadata for testing.
|
||||
|
||||
### api-all-2.0.0-sources
|
||||
This fixture is built to simulate the case where we have a jar with multiple pom files discovered when trying to determine the parent.
|
||||
This is a valid case, but not one that we covered before [PR 2231](https://github.com/anchore/syft/pull/2231)
|
||||
|
||||
### jackson-core-2.15.2
|
||||
These two fixtures are built to simulate the case where we would have a duplicate jar
|
||||
regression as seen in [issue #2130](https://github.com/anchore/syft/issues/2130)
|
|
@ -0,0 +1,4 @@
|
|||
Manifest-Version: 1.0
|
||||
Built-By: elecharny
|
||||
Created-By: Apache Maven 3.6.0
|
||||
Build-Jdk: 1.8.0_191
|
|
@ -0,0 +1,4 @@
|
|||
#Created by Apache Maven 3.6.0
|
||||
version=2.0.0
|
||||
groupId=org.apache.directory.api
|
||||
artifactId=api-all
|
|
@ -0,0 +1,135 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.directory.api</groupId>
|
||||
<artifactId>api-parent</artifactId>
|
||||
<version>2.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>api-all</artifactId>
|
||||
<name>Apache Directory API All</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>api-asn1-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>api-asn1-ber</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>api-dsml-engine</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>api-dsml-parser</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>api-i18n</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>api-ldap-client-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>api-ldap-codec-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>api-ldap-codec-standalone</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>api-ldap-extras-aci</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>api-ldap-extras-codec</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>api-ldap-extras-codec-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>api-ldap-extras-sp</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>api-ldap-extras-trigger</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>api-ldap-extras-util</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>api-ldap-model</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>api-ldap-net-mina</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>api-ldap-schema-converter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>api-ldap-schema-data</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>api-util</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<artifactSet>
|
||||
<includes>
|
||||
<include>${project.groupId}</include>
|
||||
</includes>
|
||||
</artifactSet>
|
||||
<promoteTransitiveDependencies>true</promoteTransitiveDependencies>
|
||||
<createSourcesJar>true</createSourcesJar>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,4 @@
|
|||
#Created by Apache Maven 3.6.0
|
||||
version=2.0.0
|
||||
groupId=org.apache.directory.api
|
||||
artifactId=api-asn1-api
|
|
@ -0,0 +1,99 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.directory.api</groupId>
|
||||
<artifactId>api-asn1-parent</artifactId>
|
||||
<version>2.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>api-asn1-api</artifactId>
|
||||
<name>Apache Directory API ASN.1 API</name>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<description>ASN.1 API</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>api-i18n</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestFile>META-INF/MANIFEST.MF</manifestFile>
|
||||
<addMavenDescriptor>false</addMavenDescriptor>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<inherited>true</inherited>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<manifestLocation>META-INF</manifestLocation>
|
||||
<instructions>
|
||||
<Bundle-SymbolicName>${project.groupId}.asn1.api</Bundle-SymbolicName>
|
||||
<Export-Package>
|
||||
org.apache.directory.api.asn1;version=${project.version};-noimport:=true,
|
||||
org.apache.directory.api.asn1.util;version=${project.version};-noimport:=true
|
||||
</Export-Package>
|
||||
<Import-Package>
|
||||
org.apache.directory.api.i18n;version=${project.version}
|
||||
</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
Loading…
Reference in a new issue