diff --git a/.travis.yml b/.travis.yml
index 3a09c560e72..6eda4cbb437 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -49,6 +49,7 @@ after_success:
fi;
after_failure:
+ - cat /home/travis/build/jeremylong/DependencyCheck/maven/target/it/740-aggregate/build.log
- cat /home/travis/build/jeremylong/DependencyCheck/maven/target/it/617-hierarchical-cross-deps/build.log
- cat /home/travis/build/jeremylong/DependencyCheck/maven/target/it/618-aggregator-purge/build.log
- cat /home/travis/build/jeremylong/DependencyCheck/maven/target/it/618-aggregator-update-only/build.log
diff --git a/core/src/main/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.java b/core/src/main/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.java
index bc741deaee9..023ca82a59d 100644
--- a/core/src/main/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.java
+++ b/core/src/main/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.java
@@ -403,9 +403,11 @@ private boolean hashesMatch(Dependency dependency1, Dependency dependency2) {
* @return true if on of the dependencies is a pom.xml and the identifiers
* between the two collections match; otherwise false
*/
- private boolean isShadedJar(Dependency dependency, Dependency nextDependency) {
+ protected boolean isShadedJar(Dependency dependency, Dependency nextDependency) {
if (dependency == null || dependency.getFileName() == null
- || nextDependency == null || nextDependency.getFileName() == null) {
+ || nextDependency == null || nextDependency.getFileName() == null
+ || dependency.getIdentifiers().isEmpty()
+ || nextDependency.getIdentifiers().isEmpty()) {
return false;
}
final String mainName = dependency.getFileName().toLowerCase();
diff --git a/core/src/main/java/org/owasp/dependencycheck/dependency/Dependency.java b/core/src/main/java/org/owasp/dependencycheck/dependency/Dependency.java
index f84514188a9..ca9ded7d437 100644
--- a/core/src/main/java/org/owasp/dependencycheck/dependency/Dependency.java
+++ b/core/src/main/java/org/owasp/dependencycheck/dependency/Dependency.java
@@ -192,6 +192,17 @@ public Dependency(File file, boolean isVirtual) {
determineHashes(file);
}
+ /**
+ * Constructs a new Dependency object.
+ *
+ * @param isVirtual specifies if the dependency is virtual indicating the
+ * file doesn't actually exist.
+ */
+ public Dependency(boolean isVirtual) {
+ this();
+ this.isVirtual = isVirtual;
+ }
+
/**
* Returns the file name of the dependency.
*
diff --git a/core/src/main/resources/templates/htmlReport.vsl b/core/src/main/resources/templates/htmlReport.vsl
index 1766fc12418..e680654b423 100644
--- a/core/src/main/resources/templates/htmlReport.vsl
+++ b/core/src/main/resources/templates/htmlReport.vsl
@@ -731,8 +731,8 @@ Getting Help: File Path: $enc.html($dependency.FilePath)
- MD5: $enc.html($dependency.Md5sum)
- SHA1: $enc.html($dependency.Sha1sum)
+ MD5: #if($dependency.Md5sum)$enc.html($dependency.Md5sum)#end
+ SHA1: #if($dependency.Sha1sum)$enc.html($dependency.Sha1sum)#end
#if ($dependency.projectReferences.size()==1)
Referenced In Project/Scope:
#foreach($ref in $dependency.projectReferences)
@@ -940,8 +940,8 @@ Getting Help: File Path: $enc.html($dependency.FilePath)
- MD5: $enc.html($dependency.Md5sum)
- SHA1: $enc.html($dependency.Sha1sum)
+ MD5: #if($dependency.Md5sum)$enc.html($dependency.Md5sum)#end
+ SHA1: #if($dependency.Sha1sum)$enc.html($dependency.Sha1sum)#end
#set($cnt=$cnt+1)
Evidence
diff --git a/core/src/main/resources/templates/jsonReport.vsl b/core/src/main/resources/templates/jsonReport.vsl
index d6425a7b9f8..62fefedf6d5 100644
--- a/core/src/main/resources/templates/jsonReport.vsl
+++ b/core/src/main/resources/templates/jsonReport.vsl
@@ -27,8 +27,8 @@
"isVirtual": #if($dependency.isVirtual)true#{else}false#end,
"fileName": "$enc.json($dependency.DisplayFileName)",
"filePath": "$enc.json($dependency.FilePath)",
- "md5": "$enc.json($dependency.Md5sum)",
- "sha1": "$enc.json($dependency.Sha1sum)"
+ "md5": "#if($dependency.Md5sum)$enc.json($dependency.Md5sum)#end",
+ "sha1": "#if($dependency.Sha1sum)$enc.json($dependency.Sha1sum)#end"
#if($dependency.description),"description": "$enc.json($dependency.description)"#end
#if($dependency.license),"license": "$enc.json($dependency.license)"#end
#if ($dependency.projectReferences.size()>0)
diff --git a/core/src/main/resources/templates/xmlReport.vsl b/core/src/main/resources/templates/xmlReport.vsl
index cf560147f87..ca69daa6056 100644
--- a/core/src/main/resources/templates/xmlReport.vsl
+++ b/core/src/main/resources/templates/xmlReport.vsl
@@ -48,8 +48,8 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
$enc.xml($dependency.DisplayFileName)
$enc.xml($dependency.FilePath)
- $enc.xml($dependency.Md5sum)
- $enc.xml($dependency.Sha1sum)
+ #if($dependency.Md5sum)$enc.xml($dependency.Md5sum)#end
+ #if($dependency.Sha1sum)$enc.xml($dependency.Sha1sum)#end
#if ($dependency.description)
$enc.xml($dependency.description)
#end
@@ -117,7 +117,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
#foreach($id in $dependency.getIdentifiers())
- ($id.value)
+ $enc.xml($id.value)
#if( $id.url )
$enc.xml($id.url)
#end
diff --git a/core/src/test/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzerTest.java b/core/src/test/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzerTest.java
index ee6c5ddfef9..350e187b274 100644
--- a/core/src/test/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzerTest.java
+++ b/core/src/test/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzerTest.java
@@ -17,6 +17,7 @@
*/
package org.owasp.dependencycheck.analyzer;
+import java.io.File;
import mockit.Mocked;
import mockit.Verifications;
import org.junit.Test;
@@ -59,8 +60,8 @@ public void testGetAnalysisPhase() {
}
/**
- * Test of analyze method, of class DependencyBundlingAnalyzer.
- * The actually passed dependency does not matter. The analyzer only runs once.
+ * Test of analyze method, of class DependencyBundlingAnalyzer. The actually
+ * passed dependency does not matter. The analyzer only runs once.
*/
@Test
public void testAnalyze() throws Exception {
@@ -77,10 +78,12 @@ public void testAnalyze() throws Exception {
instance.analyze(null, engineMock);
assertTrue(instance.getAnalyzed());
- new Verifications() {{
- engineMock.getDependencies();
- times = 1;
- }};
+ new Verifications() {
+ {
+ engineMock.getDependencies();
+ times = 1;
+ }
+ };
}
/**
@@ -140,4 +143,72 @@ public void testFirstPathIsShortest() {
result = instance.firstPathIsShortest(left, right);
assertEquals(expResult, result);
}
+
+ @Test
+ public void testIsShaded() {
+ DependencyBundlingAnalyzer instance = new DependencyBundlingAnalyzer();
+
+ Dependency left = null;
+ Dependency right = null;
+
+ boolean expResult = false;
+ boolean result = instance.isShadedJar(left, right);
+ assertEquals(expResult, result);
+
+ left = new Dependency();
+ expResult = false;
+ result = instance.isShadedJar(left, right);
+ assertEquals(expResult, result);
+
+ left = new Dependency(new File("/path/jar.jar"), true);
+ expResult = false;
+ result = instance.isShadedJar(left, right);
+ assertEquals(expResult, result);
+
+ right = new Dependency();
+ expResult = false;
+ result = instance.isShadedJar(left, right);
+ assertEquals(expResult, result);
+
+ right = new Dependency(new File("/path/pom.xml"), true);
+ expResult = false;
+ result = instance.isShadedJar(left, right);
+ assertEquals(expResult, result);
+
+ left.addIdentifier("test", "test", "http://example.com/test");
+ expResult = false;
+ result = instance.isShadedJar(left, right);
+ assertEquals(expResult, result);
+
+ right.addIdentifier("next", "next", "http://example.com/next");
+ expResult = false;
+ result = instance.isShadedJar(left, right);
+ assertEquals(expResult, result);
+
+ left.addIdentifier("next", "next", "http://example.com/next");
+ expResult = true;
+ result = instance.isShadedJar(left, right);
+ assertEquals(expResult, result);
+
+ left = new Dependency(new File("/path/pom.xml"), true);
+ left.addIdentifier("test", "test", "http://example.com/test");
+ right = new Dependency(new File("/path/jar.jar"), true);
+ right.addIdentifier("next", "next", "http://example.com/next");
+ expResult = false;
+ result = instance.isShadedJar(left, right);
+ assertEquals(expResult, result);
+
+ right.addIdentifier("test", "test", "http://example.com/test");
+ expResult = true;
+ result = instance.isShadedJar(left, right);
+ assertEquals(expResult, result);
+
+ left = new Dependency(new File("/path/other.jar"), true);
+ left.addIdentifier("test", "test", "http://example.com/test");
+ right = new Dependency(new File("/path/jar.jar"), true);
+ right.addIdentifier("next", "next", "http://example.com/next");
+ expResult = false;
+ result = instance.isShadedJar(left, right);
+ assertEquals(expResult, result);
+ }
}
diff --git a/maven/pom.xml b/maven/pom.xml
index 4105b776aee..e41b41163fe 100644
--- a/maven/pom.xml
+++ b/maven/pom.xml
@@ -136,6 +136,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
org.apache.maven.shared
maven-dependency-tree
+ 3.0.1
org.jmockit
@@ -195,6 +196,9 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
${project.build.directory}/it
target/local-repo
+
+ ${project.version}
+
diff --git a/maven/src/it/617-hierarchical-cross-deps/invoker.properties b/maven/src/it/617-hierarchical-cross-deps/invoker.properties
index 29b334c9e85..15acf9ef50c 100644
--- a/maven/src/it/617-hierarchical-cross-deps/invoker.properties
+++ b/maven/src/it/617-hierarchical-cross-deps/invoker.properties
@@ -16,4 +16,4 @@
# Copyright (c) 2014 Jeremy Long. All Rights Reserved.
#
-invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -X
+invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check
diff --git a/maven/src/it/618-aggregator-purge/invoker.properties b/maven/src/it/618-aggregator-purge/invoker.properties
index 46c174d8e25..0f5be4e07c1 100644
--- a/maven/src/it/618-aggregator-purge/invoker.properties
+++ b/maven/src/it/618-aggregator-purge/invoker.properties
@@ -16,5 +16,5 @@
# Copyright (c) 2014 Jeremy Long. All Rights Reserved.
#
-invoker.goals.1 = ${project.groupId}:${project.artifactId}:${project.version}:update-only -DdataDirectory=./data -Dcve.startyear=2017 -X
-invoker.goals.2 = ${project.groupId}:${project.artifactId}:${project.version}:purge -DdataDirectory=./data -X
+invoker.goals.1 = ${project.groupId}:${project.artifactId}:${project.version}:update-only -DdataDirectory=./data -Dcve.startyear=2018
+invoker.goals.2 = ${project.groupId}:${project.artifactId}:${project.version}:purge -DdataDirectory=./data
diff --git a/maven/src/it/618-aggregator-update-only/invoker.properties b/maven/src/it/618-aggregator-update-only/invoker.properties
index 1702ed25f31..b85d53e394d 100644
--- a/maven/src/it/618-aggregator-update-only/invoker.properties
+++ b/maven/src/it/618-aggregator-update-only/invoker.properties
@@ -16,4 +16,4 @@
# Copyright (c) 2014 Jeremy Long. All Rights Reserved.
#
-invoker.goals = -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:update-only -X
\ No newline at end of file
+invoker.goals = -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:update-only
\ No newline at end of file
diff --git a/maven/src/it/629-jackson-dataformat/invoker.properties b/maven/src/it/629-jackson-dataformat/invoker.properties
index 6633267fe92..c199d2648d6 100644
--- a/maven/src/it/629-jackson-dataformat/invoker.properties
+++ b/maven/src/it/629-jackson-dataformat/invoker.properties
@@ -16,4 +16,4 @@
# Copyright (c) 2014 Jeremy Long. All Rights Reserved.
#
-invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -X -Dformat=ALL
+invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -Dformat=ALL
diff --git a/maven/src/it/690-threadsafety/invoker.properties b/maven/src/it/690-threadsafety/invoker.properties
index 092fcbae279..141d562632b 100644
--- a/maven/src/it/690-threadsafety/invoker.properties
+++ b/maven/src/it/690-threadsafety/invoker.properties
@@ -16,4 +16,4 @@
# Copyright (c) 2014 Jeremy Long. All Rights Reserved.
#
-invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -X -T 10
+invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -T 10
diff --git a/maven/src/it/710-pom-parse-error/invoker.properties b/maven/src/it/710-pom-parse-error/invoker.properties
index 6633267fe92..c199d2648d6 100644
--- a/maven/src/it/710-pom-parse-error/invoker.properties
+++ b/maven/src/it/710-pom-parse-error/invoker.properties
@@ -16,4 +16,4 @@
# Copyright (c) 2014 Jeremy Long. All Rights Reserved.
#
-invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -X -Dformat=ALL
+invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -Dformat=ALL
diff --git a/maven/src/it/729-system-scope-resolved/invoker.properties b/maven/src/it/729-system-scope-resolved/invoker.properties
index 33d42889112..a074ced3027 100644
--- a/maven/src/it/729-system-scope-resolved/invoker.properties
+++ b/maven/src/it/729-system-scope-resolved/invoker.properties
@@ -16,4 +16,4 @@
# Copyright (c) 2017 Jeremy Long. All Rights Reserved.
#
-invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -X -Dformat=JSON
+invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -Dformat=JSON
diff --git a/maven/src/it/729-system-scope-skipped/invoker.properties b/maven/src/it/729-system-scope-skipped/invoker.properties
index 73d14647084..f65174ea36e 100644
--- a/maven/src/it/729-system-scope-skipped/invoker.properties
+++ b/maven/src/it/729-system-scope-skipped/invoker.properties
@@ -16,4 +16,4 @@
# Copyright (c) 2014 Jeremy Long. All Rights Reserved.
#
-invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -DskipSystemScope=true -Dformat=JSON -X
+invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -DskipSystemScope=true -Dformat=JSON
diff --git a/maven/src/it/730-multiple-suppression-files-configs/invoker.properties b/maven/src/it/730-multiple-suppression-files-configs/invoker.properties
index 9ca2f4cf476..677897a3d8b 100644
--- a/maven/src/it/730-multiple-suppression-files-configs/invoker.properties
+++ b/maven/src/it/730-multiple-suppression-files-configs/invoker.properties
@@ -15,4 +15,4 @@
#
# Copyright (c) 2017 The OWASP Foundation. All Rights Reserved.
#
-invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -X
+invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check
diff --git a/maven/src/it/730-multiple-suppression-files/invoker.properties b/maven/src/it/730-multiple-suppression-files/invoker.properties
index 9ca2f4cf476..677897a3d8b 100644
--- a/maven/src/it/730-multiple-suppression-files/invoker.properties
+++ b/maven/src/it/730-multiple-suppression-files/invoker.properties
@@ -15,4 +15,4 @@
#
# Copyright (c) 2017 The OWASP Foundation. All Rights Reserved.
#
-invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -X
+invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check
diff --git a/maven/src/it/740-aggregate/first/pom.xml b/maven/src/it/740-aggregate/first/pom.xml
new file mode 100644
index 00000000000..5361ae245ea
--- /dev/null
+++ b/maven/src/it/740-aggregate/first/pom.xml
@@ -0,0 +1,35 @@
+
+
+
+ 4.0.0
+
+ org.owasp.test.aggregate
+ aggregate-parent
+ 1.0.0-SNAPSHOT
+
+ first
+ jar
+
+
+ org.apache.commons
+ commons-collections4
+ 4.1
+
+
+
diff --git a/maven/src/it/740-aggregate/invoker.properties b/maven/src/it/740-aggregate/invoker.properties
new file mode 100644
index 00000000000..b5087cc941d
--- /dev/null
+++ b/maven/src/it/740-aggregate/invoker.properties
@@ -0,0 +1,19 @@
+#
+# This file is part of dependency-check-maven.
+#
+# Licensed 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.
+#
+# Copyright (c) 2014 Jeremy Long. All Rights Reserved.
+#
+
+invoker.goals = verify -X
diff --git a/maven/src/it/740-aggregate/pom.xml b/maven/src/it/740-aggregate/pom.xml
new file mode 100644
index 00000000000..39770600d1f
--- /dev/null
+++ b/maven/src/it/740-aggregate/pom.xml
@@ -0,0 +1,51 @@
+
+
+
+ 4.0.0
+ org.owasp.test.aggregate
+ aggregate-parent
+ 1.0.0-SNAPSHOT
+ pom
+
+ first
+ second
+ third
+
+
+
+
+ org.owasp
+ dependency-check-maven
+ ${odc.version}
+ false
+
+ XML
+ false
+
+
+
+
+ aggregate
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/maven/src/it/740-aggregate/postbuild.groovy b/maven/src/it/740-aggregate/postbuild.groovy
new file mode 100644
index 00000000000..eb55854522d
--- /dev/null
+++ b/maven/src/it/740-aggregate/postbuild.groovy
@@ -0,0 +1,34 @@
+/*
+ * This file is part of dependency-check-maven.
+ *
+ * Licensed 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.
+ *
+ * Copyright (c) 2014 Jeremy Long. All Rights Reserved.
+ */
+
+import java.nio.charset.Charset;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+
+String report = FileUtils.readFileToString(new File(basedir, "target/dependency-check-report.xml"), Charset.defaultCharset().name());
+int count = StringUtils.countMatches(report, "org.owasp.test.aggregate:fourth:1.0.0-SNAPSHOT");
+if (count == 0) {
+ System.out.println(String.format("fourth-1.0.0-SNAPSHOT was not identified"));
+ return false;
+}
+count = StringUtils.countMatches(report, "org.apache.james:apache-mime4j-core:0.7.2");
+if (count == 0) {
+ System.out.println(String.format("org.apache.james:apache-mime4j-core:0.7.2 was not identified and is a dependency of fourth-1.0.0-SNAPSHOT"));
+ return false;
+}
+return true;
\ No newline at end of file
diff --git a/maven/src/it/740-aggregate/second/pom.xml b/maven/src/it/740-aggregate/second/pom.xml
new file mode 100644
index 00000000000..c9b9caf5e05
--- /dev/null
+++ b/maven/src/it/740-aggregate/second/pom.xml
@@ -0,0 +1,35 @@
+
+
+
+ 4.0.0
+
+ org.owasp.test.aggregate
+ aggregate-parent
+ 1.0.0-SNAPSHOT
+
+ second
+ jar
+
+
+ org.owasp.test.aggregate
+ fourth
+ 1.0.0-SNAPSHOT
+
+
+
\ No newline at end of file
diff --git a/maven/src/it/740-aggregate/second/src/main/webapp/WEB-INF/web.xml b/maven/src/it/740-aggregate/second/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000000..65c96051cf0
--- /dev/null
+++ b/maven/src/it/740-aggregate/second/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,26 @@
+
+
+
+ test-app
+
+ index.html
+
+
+
diff --git a/maven/src/it/740-aggregate/third/fourth/pom.xml b/maven/src/it/740-aggregate/third/fourth/pom.xml
new file mode 100644
index 00000000000..4e138994df9
--- /dev/null
+++ b/maven/src/it/740-aggregate/third/fourth/pom.xml
@@ -0,0 +1,35 @@
+
+
+
+ 4.0.0
+
+ org.owasp.test.aggregate
+ third
+ 1.0.0-SNAPSHOT
+
+ fourth
+ jar
+
+
+ org.apache.james
+ apache-mime4j-dom
+ 0.7.2
+
+
+
\ No newline at end of file
diff --git a/maven/src/it/740-aggregate/third/fourth/src/main/webapp/WEB-INF/web.xml b/maven/src/it/740-aggregate/third/fourth/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000000..65c96051cf0
--- /dev/null
+++ b/maven/src/it/740-aggregate/third/fourth/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,26 @@
+
+
+
+ test-app
+
+ index.html
+
+
+
diff --git a/maven/src/it/740-aggregate/third/pom.xml b/maven/src/it/740-aggregate/third/pom.xml
new file mode 100644
index 00000000000..19cc22a5d1e
--- /dev/null
+++ b/maven/src/it/740-aggregate/third/pom.xml
@@ -0,0 +1,31 @@
+
+
+
+ 4.0.0
+
+ org.owasp.test.aggregate
+ aggregate-parent
+ 1.0.0-SNAPSHOT
+
+ third
+ pom
+
+ fourth
+
+
\ No newline at end of file
diff --git a/maven/src/it/815-broken-suppression-aggregate/invoker.properties b/maven/src/it/815-broken-suppression-aggregate/invoker.properties
index 34b99036143..b47175cd8ac 100644
--- a/maven/src/it/815-broken-suppression-aggregate/invoker.properties
+++ b/maven/src/it/815-broken-suppression-aggregate/invoker.properties
@@ -16,4 +16,4 @@
# Copyright (c) 2017 The OWASP Foundation. All Rights Reserved.
#
invoker.buildResult = failure
-invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:aggregate -X
+invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:aggregate
diff --git a/maven/src/it/846-site-plugin/invoker.properties b/maven/src/it/846-site-plugin/invoker.properties
index 2010c6d669c..11bb9d2052b 100644
--- a/maven/src/it/846-site-plugin/invoker.properties
+++ b/maven/src/it/846-site-plugin/invoker.properties
@@ -15,4 +15,4 @@
#
# Copyright (c) 2017 The OWASP Foundation. All Rights Reserved.
#
-invoker.goals = site -Danalyzer.central.enabled=false -Dodcversion=${project.version} -X
+invoker.goals = site -Danalyzer.central.enabled=false -Dodcversion=${project.version}
diff --git a/maven/src/it/false-positives/invoker.properties b/maven/src/it/false-positives/invoker.properties
index 6633267fe92..c199d2648d6 100644
--- a/maven/src/it/false-positives/invoker.properties
+++ b/maven/src/it/false-positives/invoker.properties
@@ -16,4 +16,4 @@
# Copyright (c) 2014 Jeremy Long. All Rights Reserved.
#
-invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -X -Dformat=ALL
+invoker.goals = install -Danalyzer.central.enabled=false ${project.groupId}:${project.artifactId}:${project.version}:check -Dformat=ALL
diff --git a/maven/src/main/java/org/owasp/dependencycheck/maven/AggregateMojo.java b/maven/src/main/java/org/owasp/dependencycheck/maven/AggregateMojo.java
index 35f2f9fe5db..572e4dc0b5a 100644
--- a/maven/src/main/java/org/owasp/dependencycheck/maven/AggregateMojo.java
+++ b/maven/src/main/java/org/owasp/dependencycheck/maven/AggregateMojo.java
@@ -64,9 +64,9 @@ public class AggregateMojo extends BaseDependencyCheckMojo {
*/
@Override
protected ExceptionCollection scanDependencies(final Engine engine) throws MojoExecutionException {
- ExceptionCollection exCol = scanArtifacts(getProject(), engine);
+ ExceptionCollection exCol = scanArtifacts(getProject(), engine, true);
for (MavenProject childProject : getDescendants(this.getProject())) {
- final ExceptionCollection ex = scanArtifacts(childProject, engine);
+ final ExceptionCollection ex = scanArtifacts(childProject, engine, true);
if (ex != null) {
if (exCol == null) {
exCol = ex;
diff --git a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java
index 0ac70d17881..84d53b6dafe 100644
--- a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java
+++ b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java
@@ -29,6 +29,7 @@
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.License;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
@@ -51,10 +52,12 @@
import org.apache.maven.shared.model.fileset.FileSet;
import org.apache.maven.shared.model.fileset.util.FileSetManager;
import org.owasp.dependencycheck.Engine;
+import org.owasp.dependencycheck.analyzer.JarAnalyzer;
import org.owasp.dependencycheck.data.nexus.MavenArtifact;
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
import org.owasp.dependencycheck.dependency.Confidence;
import org.owasp.dependencycheck.dependency.Dependency;
+import org.owasp.dependencycheck.dependency.EvidenceType;
import org.owasp.dependencycheck.dependency.Identifier;
import org.owasp.dependencycheck.dependency.Vulnerability;
import org.owasp.dependencycheck.exception.DependencyNotFoundException;
@@ -152,9 +155,9 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
@Parameter(defaultValue = "${project.build.directory}", required = true)
private File outputDirectory;
/**
- * This is a reference to the >reporting< sections outputDirectory
.
- * This cannot be configured in the dependency-check mojo directly.
- * This generally maps to "target/site".
+ * This is a reference to the >reporting< sections
+ * outputDirectory
. This cannot be configured in the
+ * dependency-check mojo directly. This generally maps to "target/site".
*/
@Parameter(property = "project.reporting.outputDirectory", readonly = true)
private File reportOutputDirectory;
@@ -228,7 +231,8 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
@Parameter(property = "connectionTimeout", defaultValue = "", required = false)
private String connectionTimeout;
/**
- * Sets whether dependency-check should check if there is a new version available.
+ * Sets whether dependency-check should check if there is a new version
+ * available.
*/
@SuppressWarnings("CanBeFinal")
@Parameter(property = "versionCheckEnabled", defaultValue = "true", required = false)
@@ -719,10 +723,25 @@ protected File getCorrectOutputDirectory(MavenProject current) {
* and scanning the dependencies
*/
protected ExceptionCollection scanArtifacts(MavenProject project, Engine engine) {
+ return scanArtifacts(project, engine, false);
+ }
+
+ /**
+ * Scans the project's artifacts and adds them to the engine's dependency
+ * list.
+ *
+ * @param project the project to scan the dependencies of
+ * @param engine the engine to use to scan the dependencies
+ * @param aggregate whether the scan is part of an aggregate build
+ * @return a collection of exceptions that may have occurred while resolving
+ * and scanning the dependencies
+ */
+ protected ExceptionCollection scanArtifacts(MavenProject project, Engine engine, boolean aggregate) {
try {
- final DependencyNode dn = dependencyGraphBuilder.buildDependencyGraph(project, null, reactorProjects);
final ProjectBuildingRequest buildingRequest = newResolveArtifactProjectBuildingRequest();
- return collectDependencies(engine, project, dn.getChildren(), buildingRequest);
+ buildingRequest.setProject(project);
+ final DependencyNode dn = dependencyGraphBuilder.buildDependencyGraph(buildingRequest, null, reactorProjects);
+ return collectDependencies(engine, project, dn.getChildren(), buildingRequest, aggregate);
} catch (DependencyGraphBuilderException ex) {
final String msg = String.format("Unable to build dependency graph on project %s", project.getName());
getLog().debug(msg, ex);
@@ -739,101 +758,111 @@ protected ExceptionCollection scanArtifacts(MavenProject project, Engine engine)
* @param nodes the list of dependency nodes, generally obtained via the
* DependencyGraphBuilder
* @param buildingRequest the Maven project building request
+ * @param aggregate whether the scan is part of an aggregate build
* @return a collection of exceptions that may have occurred while resolving
* and scanning the dependencies
*/
private ExceptionCollection collectDependencies(Engine engine, MavenProject project,
- List nodes, ProjectBuildingRequest buildingRequest) {
+ List nodes, ProjectBuildingRequest buildingRequest, boolean aggregate) {
ExceptionCollection exCol = null;
for (DependencyNode dependencyNode : nodes) {
if (artifactScopeExcluded.passes(dependencyNode.getArtifact().getScope())
|| artifactTypeExcluded.passes(dependencyNode.getArtifact().getType())) {
continue;
}
- exCol = collectDependencies(engine, project, dependencyNode.getChildren(), buildingRequest);
- try {
- boolean isResolved = false;
- File artifactFile = null;
- String artifactId = null;
- String groupId = null;
- String version = null;
- List availableVersions = null;
- if (org.apache.maven.artifact.Artifact.SCOPE_SYSTEM.equals(dependencyNode.getArtifact().getScope())) {
- for (org.apache.maven.model.Dependency d : project.getDependencies()) {
- final Artifact a = dependencyNode.getArtifact();
- if (d.getSystemPath() != null && artifactsMatch(d, a)) {
-
- artifactFile = new File(d.getSystemPath());
- isResolved = artifactFile.isFile();
- groupId = a.getGroupId();
- artifactId = a.getArtifactId();
- version = a.getVersion();
- availableVersions = a.getAvailableVersions();
- break;
- }
+ exCol = collectDependencies(engine, project, dependencyNode.getChildren(), buildingRequest, aggregate);
+ boolean isResolved = false;
+ File artifactFile = null;
+ String artifactId = null;
+ String groupId = null;
+ String version = null;
+ List availableVersions = null;
+ if (org.apache.maven.artifact.Artifact.SCOPE_SYSTEM.equals(dependencyNode.getArtifact().getScope())) {
+ for (org.apache.maven.model.Dependency d : project.getDependencies()) {
+ final Artifact a = dependencyNode.getArtifact();
+ if (d.getSystemPath() != null && artifactsMatch(d, a)) {
+
+ artifactFile = new File(d.getSystemPath());
+ isResolved = artifactFile.isFile();
+ groupId = a.getGroupId();
+ artifactId = a.getArtifactId();
+ version = a.getVersion();
+ availableVersions = a.getAvailableVersions();
+ break;
+ }
+ }
+ if (!isResolved) {
+ getLog().error("Unable to resolve system scoped dependency: " + dependencyNode.toNodeString());
+ if (exCol == null) {
+ exCol = new ExceptionCollection();
}
- if (!isResolved) {
- getLog().error("Unable to resolve system scoped dependency: " + dependencyNode.toNodeString());
+ exCol.addException(new DependencyNotFoundException("Unable to resolve system scoped dependency: "
+ + dependencyNode.toNodeString()));
+ }
+ } else {
+ final ArtifactCoordinate coordinate = TransferUtils.toArtifactCoordinate(dependencyNode.getArtifact());
+ final Artifact result;
+ try {
+ result = artifactResolver.resolveArtifact(buildingRequest, coordinate).getArtifact();
+ } catch (ArtifactResolverException ex) {
+ getLog().debug(String.format("Aggregate : %s", aggregate));
+ boolean addException = true;
+ if (!aggregate || addReactorDependency(engine, dependencyNode.getArtifact())) {
+ addException = false;
+ }
+ if (addException) {
if (exCol == null) {
exCol = new ExceptionCollection();
}
- exCol.addException(new DependencyNotFoundException("Unable to resolve system scoped dependency: "
- + dependencyNode.toNodeString()));
+ exCol.addException(ex);
}
- } else {
- final ArtifactCoordinate coordinate = TransferUtils.toArtifactCoordinate(dependencyNode.getArtifact());
- final Artifact result = artifactResolver.resolveArtifact(buildingRequest, coordinate).getArtifact();
- isResolved = result.isResolved();
- artifactFile = result.getFile();
- groupId = result.getGroupId();
- artifactId = result.getArtifactId();
- version = result.getVersion();
- availableVersions = result.getAvailableVersions();
+ continue;
}
- if (isResolved && artifactFile != null) {
- final List deps = engine.scan(artifactFile.getAbsoluteFile(),
- project.getName() + ":" + dependencyNode.getArtifact().getScope());
- if (deps != null) {
- if (deps.size() == 1) {
- final Dependency d = deps.get(0);
- if (d != null) {
- final MavenArtifact ma = new MavenArtifact(groupId, artifactId, version);
- d.addAsEvidence("pom", ma, Confidence.HIGHEST);
- if (availableVersions != null) {
- for (ArtifactVersion av : availableVersions) {
- d.addAvailableVersion(av.toString());
- }
+ isResolved = result.isResolved();
+ artifactFile = result.getFile();
+ groupId = result.getGroupId();
+ artifactId = result.getArtifactId();
+ version = result.getVersion();
+ availableVersions = result.getAvailableVersions();
+ }
+ if (isResolved && artifactFile != null) {
+ final List deps = engine.scan(artifactFile.getAbsoluteFile(),
+ project.getName() + ":" + dependencyNode.getArtifact().getScope());
+ if (deps != null) {
+ if (deps.size() == 1) {
+ final Dependency d = deps.get(0);
+ if (d != null) {
+ final MavenArtifact ma = new MavenArtifact(groupId, artifactId, version);
+ d.addAsEvidence("pom", ma, Confidence.HIGHEST);
+ if (availableVersions != null) {
+ for (ArtifactVersion av : availableVersions) {
+ d.addAvailableVersion(av.toString());
}
- getLog().debug(String.format("Adding project reference %s on dependency %s",
- project.getName(), d.getDisplayFileName()));
}
- } else if (getLog().isDebugEnabled()) {
- final String msg = String.format("More than 1 dependency was identified in first pass scan of '%s' in project %s",
- dependencyNode.getArtifact().getId(), project.getName());
- getLog().debug(msg);
+ getLog().debug(String.format("Adding project reference %s on dependency %s",
+ project.getName(), d.getDisplayFileName()));
}
- } else if ("import".equals(dependencyNode.getArtifact().getScope())) {
- final String msg = String.format("Skipping '%s:%s' in project %s as it uses an `import` scope",
- dependencyNode.getArtifact().getId(), dependencyNode.getArtifact().getScope(), project.getName());
+ } else if (getLog().isDebugEnabled()) {
+ final String msg = String.format("More than 1 dependency was identified in first pass scan of '%s' in project %s",
+ dependencyNode.getArtifact().getId(), project.getName());
getLog().debug(msg);
- } else {
- final String msg = String.format("No analyzer could be found for '%s:%s' in project %s",
- dependencyNode.getArtifact().getId(), dependencyNode.getArtifact().getScope(), project.getName());
- getLog().warn(msg);
}
- } else {
- final String msg = String.format("Unable to resolve '%s' in project %s",
- dependencyNode.getArtifact().getId(), project.getName());
+ } else if ("import".equals(dependencyNode.getArtifact().getScope())) {
+ final String msg = String.format("Skipping '%s:%s' in project %s as it uses an `import` scope",
+ dependencyNode.getArtifact().getId(), dependencyNode.getArtifact().getScope(), project.getName());
getLog().debug(msg);
- if (exCol == null) {
- exCol = new ExceptionCollection();
- }
+ } else {
+ final String msg = String.format("No analyzer could be found for '%s:%s' in project %s",
+ dependencyNode.getArtifact().getId(), dependencyNode.getArtifact().getScope(), project.getName());
+ getLog().warn(msg);
}
- } catch (ArtifactResolverException ex) {
+ } else {
+ final String msg = String.format("Unable to resolve '%s' in project %s",
+ dependencyNode.getArtifact().getId(), project.getName());
+ getLog().debug(msg);
if (exCol == null) {
exCol = new ExceptionCollection();
}
- exCol.addException(ex);
}
}
@@ -870,6 +899,84 @@ private ExceptionCollection collectDependencies(Engine engine, MavenProject proj
return exCol;
}
+ /**
+ * Checks if the current artifact is actually in the reactor projects that
+ * have not yet been built. If true a virtual dependency is created based on
+ * the evidence in the project.
+ *
+ * @param engine a reference to the engine being used to scan
+ * @param artifact the artifact being analyzed in the mojo
+ * @return true
if the artifact is in the reactor; otherwise
+ * false
+ */
+ private boolean addReactorDependency(Engine engine, Artifact artifact) {
+
+ getLog().debug(String.format("Checking the reactor projects (%d) for %s:%s:%s",
+ reactorProjects.size(),
+ artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion()));
+
+ for (MavenProject prj : reactorProjects) {
+
+ getLog().debug(String.format("Comparing %s:%s:%s to %s:%s:%s",
+ artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(),
+ prj.getGroupId(), prj.getArtifactId(), prj.getVersion()));
+
+ if (prj.getArtifactId().equals(artifact.getArtifactId())
+ && prj.getGroupId().equals(artifact.getGroupId())
+ && prj.getVersion().equals(artifact.getVersion())) {
+
+ final String displayName = String.format("%s:%s:%s",
+ prj.getGroupId(), prj.getArtifactId(), prj.getVersion());
+ getLog().info(String.format("Unable to resolve %s as it has not been built yet - creating a virtual dependency instead.", displayName));
+ File pom = new File(prj.getBasedir(), "pom.xml");
+ Dependency d;
+ if (pom.isFile()) {
+ getLog().debug("Adding virtual dependency from pom.xml");
+ d = new Dependency(pom, true);
+ } else {
+ d = new Dependency(true);
+ }
+ d.setDisplayFileName(displayName);
+
+ d.addEvidence(EvidenceType.PRODUCT, "project", "artifactid", prj.getArtifactId(), Confidence.HIGHEST);
+ d.addEvidence(EvidenceType.VENDOR, "project", "artifactid", prj.getArtifactId(), Confidence.LOW);
+
+ d.addEvidence(EvidenceType.VENDOR, "project", "groupid", prj.getGroupId(), Confidence.HIGHEST);
+ d.addEvidence(EvidenceType.PRODUCT, "project", "groupid", prj.getGroupId(), Confidence.LOW);
+ d.setEcosystem(JarAnalyzer.DEPENDENCY_ECOSYSTEM);
+ Identifier id = new Identifier();
+ id.setType("maven");
+ id.setConfidence(Confidence.HIGHEST);
+ id.setValue(displayName);
+ d.addIdentifier(id);
+ //TODO unify the setName/version and package path - they are equivelent ideas submitted by two seperate committers
+ d.setName(String.format("%s:%s", prj.getGroupId(), prj.getArtifactId()));
+ d.setVersion(prj.getVersion());
+ d.setPackagePath(displayName);
+ if (prj.getDescription() != null) {
+ JarAnalyzer.addDescription(d, prj.getDescription(), "project", "description");
+ }
+ for (License l : prj.getLicenses()) {
+ StringBuilder license = new StringBuilder();
+ if (l.getName() != null) {
+ license.append(l.getName());
+ }
+ if (l.getUrl() != null) {
+ license.append(" ").append(l.getUrl());
+ }
+ if (d.getLicense() == null) {
+ d.setLicense(license.toString());
+ } else if (!d.getLicense().contains(license)) {
+ d.setLicense(String.format("%s%n%s", d.getLicense(), license.toString()));
+ }
+ }
+ engine.addDependency(d);
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* Determines if the groupId, artifactId, and version of the Maven
* dependency and artifact match.
@@ -974,7 +1081,8 @@ protected void runCheck() throws MojoExecutionException, MojoFailureException {
* @param currentEx the primary exception collection
* @param newEx the new exception collection to add
* @return the combined exception collection
- * @throws MojoExecutionException thrown if dependency-check is configured to fail on errors
+ * @throws MojoExecutionException thrown if dependency-check is configured
+ * to fail on errors
*/
private ExceptionCollection handleAnalysisExceptions(ExceptionCollection currentEx, ExceptionCollection newEx) throws MojoExecutionException {
ExceptionCollection returnEx = currentEx;
diff --git a/pom.xml b/pom.xml
index 1e9daec1139..c2fb00d1b18 100644
--- a/pom.xml
+++ b/pom.xml
@@ -173,7 +173,7 @@ Copyright (c) 2012 - Jeremy Long
1.4
- 2.2
+ 3.0.1
1.0.4
0.9.1