Skip to content

Commit

Permalink
fix(java): use dependencyManagement from root/child pom's for depen…
Browse files Browse the repository at this point in the history
…dencies from parents (aquasecurity#7497)
  • Loading branch information
DmitriyLewen authored and fhielpos committed Dec 20, 2024
1 parent 0bb02d1 commit d778574
Show file tree
Hide file tree
Showing 6 changed files with 223 additions and 3 deletions.
20 changes: 17 additions & 3 deletions pkg/dependency/parser/java/pom/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,8 +335,20 @@ func (p *Parser) analyze(pom *pom, opts analysisOptions) (analysisResult, error)
p.releaseRemoteRepos = lo.Uniq(append(pomReleaseRemoteRepos, p.releaseRemoteRepos...))
p.snapshotRemoteRepos = lo.Uniq(append(pomSnapshotRemoteRepos, p.snapshotRemoteRepos...))

// We need to forward dependencyManagements from current and root pom to Parent,
// to use them for dependencies in parent.
// For better understanding see the following tests:
// - `dependency from parent uses version from child pom depManagement`
// - `dependency from parent uses version from root pom depManagement`
//
// depManagements from root pom has higher priority than depManagements from current pom.
depManagementForParent := lo.UniqBy(append(opts.depManagement, pom.content.DependencyManagement.Dependencies.Dependency...),
func(dep pomDependency) string {
return dep.Name()
})

// Parent
parent, err := p.parseParent(pom.filePath, pom.content.Parent)
parent, err := p.parseParent(pom.filePath, pom.content.Parent, depManagementForParent)
if err != nil {
return analysisResult{}, xerrors.Errorf("parent error: %w", err)
}
Expand Down Expand Up @@ -477,7 +489,7 @@ func excludeDep(exclusions map[string]struct{}, art artifact) bool {
return false
}

func (p *Parser) parseParent(currentPath string, parent pomParent) (analysisResult, error) {
func (p *Parser) parseParent(currentPath string, parent pomParent, rootDepManagement []pomDependency) (analysisResult, error) {
// Pass nil properties so that variables in <parent> are not evaluated.
target := newArtifact(parent.GroupId, parent.ArtifactId, parent.Version, nil, nil)
// if version is property (e.g. ${revision}) - we still need to parse this pom
Expand All @@ -499,7 +511,9 @@ func (p *Parser) parseParent(currentPath string, parent pomParent) (analysisResu
logger.Debug("Parent POM not found", log.Err(err))
}

result, err := p.analyze(parentPOM, analysisOptions{})
result, err := p.analyze(parentPOM, analysisOptions{
depManagement: rootDepManagement,
})
if err != nil {
return analysisResult{}, xerrors.Errorf("analyze error: %w", err)
}
Expand Down
96 changes: 96 additions & 0 deletions pkg/dependency/parser/java/pom/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1499,6 +1499,102 @@ func TestPom_Parse(t *testing.T) {
},
},
},
// [INFO] com.example:root-depManagement-in-parent:jar:1.0.0
// [INFO] \- org.example:example-dependency:jar:2.0.0:compile
// [INFO] \- org.example:example-api:jar:1.0.1:compile
{
name: "dependency from parent uses version from root pom depManagement",
inputFile: filepath.Join("testdata", "use-root-dep-management-in-parent", "pom.xml"),
local: true,
want: []ftypes.Package{
{
ID: "com.example:root-depManagement-in-parent:1.0.0",
Name: "com.example:root-depManagement-in-parent",
Version: "1.0.0",
Relationship: ftypes.RelationshipRoot,
},
{
ID: "org.example:example-dependency:2.0.0",
Name: "org.example:example-dependency",
Version: "2.0.0",
Relationship: ftypes.RelationshipDirect,
Locations: ftypes.Locations{
{
StartLine: 25,
EndLine: 29,
},
},
},
{
ID: "org.example:example-api:1.0.1",
Name: "org.example:example-api",
Version: "1.0.1",
Relationship: ftypes.RelationshipIndirect,
},
},
wantDeps: []ftypes.Dependency{
{
ID: "com.example:root-depManagement-in-parent:1.0.0",
DependsOn: []string{
"org.example:example-dependency:2.0.0",
},
},
{
ID: "org.example:example-dependency:2.0.0",
DependsOn: []string{
"org.example:example-api:1.0.1",
},
},
},
},
// [INFO] com.example:root-depManagement-in-parent:jar:1.0.0
// [INFO] \- org.example:example-dependency:jar:2.0.0:compile
// [INFO] \- org.example:example-api:jar:2.0.1:compile
{
name: "dependency from parent uses version from child pom depManagement",
inputFile: filepath.Join("testdata", "use-dep-management-from-child-in-parent", "pom.xml"),
local: true,
want: []ftypes.Package{
{
ID: "com.example:root-depManagement-in-parent:1.0.0",
Name: "com.example:root-depManagement-in-parent",
Version: "1.0.0",
Relationship: ftypes.RelationshipRoot,
},
{
ID: "org.example:example-dependency:2.0.0",
Name: "org.example:example-dependency",
Version: "2.0.0",
Relationship: ftypes.RelationshipDirect,
Locations: ftypes.Locations{
{
StartLine: 15,
EndLine: 19,
},
},
},
{
ID: "org.example:example-api:2.0.1",
Name: "org.example:example-api",
Version: "2.0.1",
Relationship: ftypes.RelationshipIndirect,
},
},
wantDeps: []ftypes.Dependency{
{
ID: "com.example:root-depManagement-in-parent:1.0.0",
DependsOn: []string{
"org.example:example-dependency:2.0.0",
},
},
{
ID: "org.example:example-dependency:2.0.0",
DependsOn: []string{
"org.example:example-api:2.0.1",
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.example</groupId>
<artifactId>example-parent</artifactId>
<version>3.0.0</version>
</parent>

<groupId>org.example</groupId>
<artifactId>example-dependency</artifactId>
<version>2.0.0</version>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>example-api</artifactId>
<version>2.0.1</version>
</dependency>
</dependencies>
</dependencyManagement>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>org.example</groupId>
<artifactId>example-parent</artifactId>
<version>3.0.0</version>
<packaging>pom</packaging>

<properties>
<api.version>3.0.1</api.version>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>example-api</artifactId>
<version>${api.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>example-api</artifactId>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.example</groupId>
<artifactId>root-depManagement-in-parent</artifactId>
<version>1.0.0</version>


<properties>
<api.version>1.0.1</api.version>
</properties>

<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>example-dependency</artifactId>
<version>2.0.0</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.example</groupId>
<artifactId>root-depManagement-in-parent</artifactId>
<version>1.0.0</version>


<properties>
<api.version>1.0.1</api.version>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>example-api</artifactId>
<version>${api.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>example-dependency</artifactId>
<version>2.0.0</version>
</dependency>
</dependencies>
</project>

0 comments on commit d778574

Please sign in to comment.