mirror of
https://github.com/ysoftdevs/DependencyCheck.git
synced 2026-03-24 18:11:47 +01:00
checkstyle/findbugs corrections
This commit is contained in:
@@ -35,11 +35,14 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* This analyzer ensures dependencies that should be grouped together, to remove excess noise from the report, are grouped. An
|
* This analyzer ensures dependencies that should be grouped together, to remove
|
||||||
* example would be Spring, Spring Beans, Spring MVC, etc. If they are all for the same version and have the same relative path
|
* excess noise from the report, are grouped. An example would be Spring, Spring
|
||||||
* then these should be grouped into a single dependency under the core/main library.</p>
|
* Beans, Spring MVC, etc. If they are all for the same version and have the
|
||||||
|
* same relative path then these should be grouped into a single dependency
|
||||||
|
* under the core/main library.</p>
|
||||||
* <p>
|
* <p>
|
||||||
* Note, this grouping only works on dependencies with identified CVE entries</p>
|
* Note, this grouping only works on dependencies with identified CVE
|
||||||
|
* entries</p>
|
||||||
*
|
*
|
||||||
* @author Jeremy Long
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
@@ -92,12 +95,14 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
|||||||
//</editor-fold>
|
//</editor-fold>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Analyzes a set of dependencies. If they have been found to have the same base path and the same set of identifiers they are
|
* Analyzes a set of dependencies. If they have been found to have the same
|
||||||
* likely related. The related dependencies are bundled into a single reportable item.
|
* base path and the same set of identifiers they are likely related. The
|
||||||
|
* related dependencies are bundled into a single reportable item.
|
||||||
*
|
*
|
||||||
* @param ignore this analyzer ignores the dependency being analyzed
|
* @param ignore this analyzer ignores the dependency being analyzed
|
||||||
* @param engine the engine that is scanning the dependencies
|
* @param engine the engine that is scanning the dependencies
|
||||||
* @throws AnalysisException is thrown if there is an error reading the JAR file.
|
* @throws AnalysisException is thrown if there is an error reading the JAR
|
||||||
|
* file.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void analyze(Dependency ignore, Engine engine) throws AnalysisException {
|
public void analyze(Dependency ignore, Engine engine) throws AnalysisException {
|
||||||
@@ -138,11 +143,11 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
|||||||
mergeDependencies(nextDependency, dependency, dependenciesToRemove);
|
mergeDependencies(nextDependency, dependency, dependenciesToRemove);
|
||||||
break; //since we merged into the next dependency - skip forward to the next in mainIterator
|
break; //since we merged into the next dependency - skip forward to the next in mainIterator
|
||||||
}
|
}
|
||||||
} else if ( isSameRubyGem(dependency, nextDependency) ) {
|
} else if (isSameRubyGem(dependency, nextDependency)) {
|
||||||
Dependency main = getMainGemspecDependency(dependency, nextDependency);
|
final Dependency main = getMainGemspecDependency(dependency, nextDependency);
|
||||||
if (main == dependency) {
|
if (main == dependency) {
|
||||||
mergeDependencies(dependency, nextDependency, dependenciesToRemove);
|
mergeDependencies(dependency, nextDependency, dependenciesToRemove);
|
||||||
} else {
|
} else {
|
||||||
mergeDependencies(nextDependency, dependency, dependenciesToRemove);
|
mergeDependencies(nextDependency, dependency, dependenciesToRemove);
|
||||||
break; //since we merged into the next dependency - skip forward to the next in mainIterator
|
break; //since we merged into the next dependency - skip forward to the next in mainIterator
|
||||||
}
|
}
|
||||||
@@ -160,10 +165,11 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
|||||||
* Adds the relatedDependency to the dependency's related dependencies.
|
* Adds the relatedDependency to the dependency's related dependencies.
|
||||||
*
|
*
|
||||||
* @param dependency the main dependency
|
* @param dependency the main dependency
|
||||||
* @param relatedDependency a collection of dependencies to be removed from the main analysis loop, this is the source of
|
* @param relatedDependency a collection of dependencies to be removed from
|
||||||
* dependencies to remove
|
* the main analysis loop, this is the source of dependencies to remove
|
||||||
* @param dependenciesToRemove a collection of dependencies that will be removed from the main analysis loop, this function
|
* @param dependenciesToRemove a collection of dependencies that will be
|
||||||
* adds to this collection
|
* removed from the main analysis loop, this function adds to this
|
||||||
|
* collection
|
||||||
*/
|
*/
|
||||||
private void mergeDependencies(final Dependency dependency, final Dependency relatedDependency, final Set<Dependency> dependenciesToRemove) {
|
private void mergeDependencies(final Dependency dependency, final Dependency relatedDependency, final Set<Dependency> dependenciesToRemove) {
|
||||||
dependency.addRelatedDependency(relatedDependency);
|
dependency.addRelatedDependency(relatedDependency);
|
||||||
@@ -179,7 +185,8 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to trim a maven repo to a common base path. This is typically [drive]\[repo_location]\repository\[path1]\[path2].
|
* Attempts to trim a maven repo to a common base path. This is typically
|
||||||
|
* [drive]\[repo_location]\repository\[path1]\[path2].
|
||||||
*
|
*
|
||||||
* @param path the path to trim
|
* @param path the path to trim
|
||||||
* @return a string representing the base path.
|
* @return a string representing the base path.
|
||||||
@@ -204,11 +211,13 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the file names (and version if it exists) of the two dependencies are sufficiently similar.
|
* Returns true if the file names (and version if it exists) of the two
|
||||||
|
* dependencies are sufficiently similar.
|
||||||
*
|
*
|
||||||
* @param dependency1 a dependency2 to compare
|
* @param dependency1 a dependency2 to compare
|
||||||
* @param dependency2 a dependency2 to compare
|
* @param dependency2 a dependency2 to compare
|
||||||
* @return true if the identifiers in the two supplied dependencies are equal
|
* @return true if the identifiers in the two supplied dependencies are
|
||||||
|
* equal
|
||||||
*/
|
*/
|
||||||
private boolean fileNameMatch(Dependency dependency1, Dependency dependency2) {
|
private boolean fileNameMatch(Dependency dependency1, Dependency dependency2) {
|
||||||
if (dependency1 == null || dependency1.getFileName() == null
|
if (dependency1 == null || dependency1.getFileName() == null
|
||||||
@@ -236,11 +245,13 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the CPE identifiers in the two supplied dependencies are equal.
|
* Returns true if the CPE identifiers in the two supplied dependencies are
|
||||||
|
* equal.
|
||||||
*
|
*
|
||||||
* @param dependency1 a dependency2 to compare
|
* @param dependency1 a dependency2 to compare
|
||||||
* @param dependency2 a dependency2 to compare
|
* @param dependency2 a dependency2 to compare
|
||||||
* @return true if the identifiers in the two supplied dependencies are equal
|
* @return true if the identifiers in the two supplied dependencies are
|
||||||
|
* equal
|
||||||
*/
|
*/
|
||||||
private boolean cpeIdentifiersMatch(Dependency dependency1, Dependency dependency2) {
|
private boolean cpeIdentifiersMatch(Dependency dependency1, Dependency dependency2) {
|
||||||
if (dependency1 == null || dependency1.getIdentifiers() == null
|
if (dependency1 == null || dependency1.getIdentifiers() == null
|
||||||
@@ -312,35 +323,51 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bundling Ruby gems that are identified from different .gemspec files but denote the same package path.
|
* Bundling Ruby gems that are identified from different .gemspec files but
|
||||||
* This happens when Ruby bundler installs an app's dependencies by running "bundle install".
|
* denote the same package path. This happens when Ruby bundler installs an
|
||||||
|
* application's dependencies by running "bundle install".
|
||||||
|
*
|
||||||
|
* @param dependency1 dependency to compare
|
||||||
|
* @param dependency2 dependency to compare
|
||||||
|
* @return true if the the dependencies being analyzed appear to be the
|
||||||
|
* same; otherwise false
|
||||||
*/
|
*/
|
||||||
private boolean isSameRubyGem(Dependency dependency1, Dependency dependency2) {
|
private boolean isSameRubyGem(Dependency dependency1, Dependency dependency2) {
|
||||||
if (dependency1 == null || dependency2 == null ||
|
if (dependency1 == null || dependency2 == null
|
||||||
!dependency1.getFileName().endsWith(".gemspec") ||
|
|| !dependency1.getFileName().endsWith(".gemspec")
|
||||||
!dependency2.getFileName().endsWith(".gemspec") ||
|
|| !dependency2.getFileName().endsWith(".gemspec")
|
||||||
dependency1.getPackagePath() == null ||
|
|| dependency1.getPackagePath() == null
|
||||||
dependency2.getPackagePath() == null) {
|
|| dependency2.getPackagePath() == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (dependency1.getPackagePath().equalsIgnoreCase(dependency2.getPackagePath()))
|
if (dependency1.getPackagePath().equalsIgnoreCase(dependency2.getPackagePath())) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ruby gems installed by "bundle install" can have zero or more *.gemspec files, all of which have the same packagePath and should be grouped.
|
* Ruby gems installed by "bundle install" can have zero or more *.gemspec
|
||||||
* If one of these gemspec is from <parent>/specifications/*.gemspec, because it is a stub with fully resolved gem meta-data
|
* files, all of which have the same packagePath and should be grouped. If
|
||||||
* created by Ruby bundler, this dependency should be the main one. Otherwise, use dependency2 as main.
|
* one of these gemspec is from <parent>/specifications/*.gemspec, because
|
||||||
|
* it is a stub with fully resolved gem meta-data created by Ruby bundler,
|
||||||
|
* this dependency should be the main one. Otherwise, use dependency2 as
|
||||||
|
* main.
|
||||||
*
|
*
|
||||||
* This method returns null if any dependency is not from *.gemspec, or the two do not have the same packagePath.
|
* This method returns null if any dependency is not from *.gemspec, or the
|
||||||
* In this case, they should not be grouped.
|
* two do not have the same packagePath. In this case, they should not be
|
||||||
|
* grouped.
|
||||||
|
*
|
||||||
|
* @param dependency1 dependency to compare
|
||||||
|
* @param dependency2 dependency to compare
|
||||||
|
* @return the main dependency; or null if a gemspec is not included in the
|
||||||
|
* analysis
|
||||||
*/
|
*/
|
||||||
private Dependency getMainGemspecDependency(Dependency dependency1, Dependency dependency2) {
|
private Dependency getMainGemspecDependency(Dependency dependency1, Dependency dependency2) {
|
||||||
if (isSameRubyGem(dependency1, dependency2)) {
|
if (isSameRubyGem(dependency1, dependency2)) {
|
||||||
final File lFile = dependency1.getActualFile();
|
final File lFile = dependency1.getActualFile();
|
||||||
File left = lFile.getParentFile();
|
final File left = lFile.getParentFile();
|
||||||
if (left != null && left.getName().equalsIgnoreCase("specifications")) {
|
if (left != null && left.getName().equalsIgnoreCase("specifications")) {
|
||||||
return dependency1;
|
return dependency1;
|
||||||
}
|
}
|
||||||
@@ -350,12 +377,13 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is likely a very broken attempt at determining if the 'left' dependency is the 'core' library in comparison to the
|
* This is likely a very broken attempt at determining if the 'left'
|
||||||
* 'right' library.
|
* dependency is the 'core' library in comparison to the 'right' library.
|
||||||
*
|
*
|
||||||
* @param left the dependency to test
|
* @param left the dependency to test
|
||||||
* @param right the dependency to test against
|
* @param right the dependency to test against
|
||||||
* @return a boolean indicating whether or not the left dependency should be considered the "core" version.
|
* @return a boolean indicating whether or not the left dependency should be
|
||||||
|
* considered the "core" version.
|
||||||
*/
|
*/
|
||||||
boolean isCore(Dependency left, Dependency right) {
|
boolean isCore(Dependency left, Dependency right) {
|
||||||
final String leftName = left.getFileName().toLowerCase();
|
final String leftName = left.getFileName().toLowerCase();
|
||||||
@@ -391,11 +419,13 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compares the SHA1 hashes of two dependencies to determine if they are equal.
|
* Compares the SHA1 hashes of two dependencies to determine if they are
|
||||||
|
* equal.
|
||||||
*
|
*
|
||||||
* @param dependency1 a dependency object to compare
|
* @param dependency1 a dependency object to compare
|
||||||
* @param dependency2 a dependency object to compare
|
* @param dependency2 a dependency object to compare
|
||||||
* @return true if the sha1 hashes of the two dependencies match; otherwise false
|
* @return true if the sha1 hashes of the two dependencies match; otherwise
|
||||||
|
* false
|
||||||
*/
|
*/
|
||||||
private boolean hashesMatch(Dependency dependency1, Dependency dependency2) {
|
private boolean hashesMatch(Dependency dependency1, Dependency dependency2) {
|
||||||
if (dependency1 == null || dependency2 == null || dependency1.getSha1sum() == null || dependency2.getSha1sum() == null) {
|
if (dependency1 == null || dependency2 == null || dependency1.getSha1sum() == null || dependency2.getSha1sum() == null) {
|
||||||
@@ -405,12 +435,13 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if the jar is shaded and the created pom.xml identified the same CPE as the jar - if so, the pom.xml dependency
|
* Determines if the jar is shaded and the created pom.xml identified the
|
||||||
* should be removed.
|
* same CPE as the jar - if so, the pom.xml dependency should be removed.
|
||||||
*
|
*
|
||||||
* @param dependency a dependency to check
|
* @param dependency a dependency to check
|
||||||
* @param nextDependency another dependency to check
|
* @param nextDependency another dependency to check
|
||||||
* @return true if on of the dependencies is a pom.xml and the identifiers between the two collections match; otherwise false
|
* @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) {
|
private boolean isShadedJar(Dependency dependency, Dependency nextDependency) {
|
||||||
final String mainName = dependency.getFileName().toLowerCase();
|
final String mainName = dependency.getFileName().toLowerCase();
|
||||||
@@ -424,12 +455,13 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines which path is shortest; if path lengths are equal then we use compareTo of the string method to determine if the
|
* Determines which path is shortest; if path lengths are equal then we use
|
||||||
* first path is smaller.
|
* compareTo of the string method to determine if the first path is smaller.
|
||||||
*
|
*
|
||||||
* @param left the first path to compare
|
* @param left the first path to compare
|
||||||
* @param right the second path to compare
|
* @param right the second path to compare
|
||||||
* @return <code>true</code> if the leftPath is the shortest; otherwise <code>false</code>
|
* @return <code>true</code> if the leftPath is the shortest; otherwise
|
||||||
|
* <code>false</code>
|
||||||
*/
|
*/
|
||||||
protected boolean firstPathIsShortest(String left, String right) {
|
protected boolean firstPathIsShortest(String left, String right) {
|
||||||
final String leftPath = left.replace('\\', '/');
|
final String leftPath = left.replace('\\', '/');
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
/**
|
/**
|
||||||
* Python init files
|
* Python init files
|
||||||
*/
|
*/
|
||||||
private static final NameFileFilter IGNORED_FILES = new NameFileFilter(new String[] {
|
private static final NameFileFilter IGNORED_FILES = new NameFileFilter(new String[]{
|
||||||
"__init__.py",
|
"__init__.py",
|
||||||
"__init__.pyc",
|
"__init__.pyc",
|
||||||
"__init__.pyo",
|
"__init__.pyo",
|
||||||
@@ -81,7 +81,8 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
*
|
*
|
||||||
* @param dependency the dependency to analyze.
|
* @param dependency the dependency to analyze.
|
||||||
* @param engine the engine that is scanning the dependencies
|
* @param engine the engine that is scanning the dependencies
|
||||||
* @throws AnalysisException is thrown if there is an error reading the JAR file.
|
* @throws AnalysisException is thrown if there is an error reading the JAR
|
||||||
|
* file.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
|
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
@@ -107,13 +108,6 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
fileName, Confidence.MEDIUM);
|
fileName, Confidence.MEDIUM);
|
||||||
}
|
}
|
||||||
|
|
||||||
//add as vendor and product evidence
|
|
||||||
// if (fileName.contains("-")) {
|
|
||||||
// dependency.getProductEvidence().addEvidence("file", "name",
|
|
||||||
// fileName, Confidence.HIGHEST);
|
|
||||||
// dependency.getVendorEvidence().addEvidence("file", "name",
|
|
||||||
// fileName, Confidence.HIGHEST);
|
|
||||||
// } else
|
|
||||||
if (!IGNORED_FILES.accept(f)) {
|
if (!IGNORED_FILES.accept(f)) {
|
||||||
dependency.getProductEvidence().addEvidence("file", "name",
|
dependency.getProductEvidence().addEvidence("file", "name",
|
||||||
fileName, Confidence.HIGH);
|
fileName, Confidence.HIGH);
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
@@ -578,7 +577,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
addMatchingValues(classes, trimmedDescription, dependency.getProductEvidence());
|
addMatchingValues(classes, trimmedDescription, dependency.getProductEvidence());
|
||||||
}
|
}
|
||||||
|
|
||||||
String projectURL = pom.getProjectURL();
|
final String projectURL = pom.getProjectURL();
|
||||||
if (projectURL != null && !projectURL.trim().isEmpty()) {
|
if (projectURL != null && !projectURL.trim().isEmpty()) {
|
||||||
dependency.getVendorEvidence().addEvidence("pom", "url", projectURL, Confidence.HIGHEST);
|
dependency.getVendorEvidence().addEvidence("pom", "url", projectURL, Confidence.HIGHEST);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ import java.util.regex.Matcher;
|
|||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to analyze a Python package, and collect information that can be used to determine the associated CPE.
|
* Used to analyze a Python package, and collect information that can be used to
|
||||||
|
* determine the associated CPE.
|
||||||
*
|
*
|
||||||
* @author Dale Visser
|
* @author Dale Visser
|
||||||
*/
|
*/
|
||||||
@@ -166,7 +167,8 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
*
|
*
|
||||||
* @param dependency the dependency being analyzed
|
* @param dependency the dependency being analyzed
|
||||||
* @param engine the engine being used to perform the scan
|
* @param engine the engine being used to perform the scan
|
||||||
* @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency
|
* @throws AnalysisException thrown if there is an unrecoverable error
|
||||||
|
* analyzing the dependency
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void analyzeFileType(Dependency dependency, Engine engine)
|
protected void analyzeFileType(Dependency dependency, Engine engine)
|
||||||
@@ -175,9 +177,9 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
final File parent = file.getParentFile();
|
final File parent = file.getParentFile();
|
||||||
final String parentName = parent.getName();
|
final String parentName = parent.getName();
|
||||||
if (INIT_PY_FILTER.accept(file)) {
|
if (INIT_PY_FILTER.accept(file)) {
|
||||||
//by definition, the containing folder of __init__.py is considered the package, even the file is empty:
|
//by definition, the containing folder of __init__.py is considered the package, even the file is empty:
|
||||||
//"The __init__.py files are required to make Python treat the directories as containing packages"
|
//"The __init__.py files are required to make Python treat the directories as containing packages"
|
||||||
//see section "6.4 Packages" from https://docs.python.org/2/tutorial/modules.html;
|
//see section "6.4 Packages" from https://docs.python.org/2/tutorial/modules.html;
|
||||||
dependency.setDisplayFileName(parentName + "/__init__.py");
|
dependency.setDisplayFileName(parentName + "/__init__.py");
|
||||||
dependency.getProductEvidence().addEvidence(file.getName(),
|
dependency.getProductEvidence().addEvidence(file.getName(),
|
||||||
"PackageName", parentName, Confidence.HIGHEST);
|
"PackageName", parentName, Confidence.HIGHEST);
|
||||||
@@ -188,8 +190,7 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
analyzeFileContents(dependency, sourceFile);
|
analyzeFileContents(dependency, sourceFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// copy, alter and set in case some other thread is iterating over
|
// copy, alter and set in case some other thread is iterating over
|
||||||
final List<Dependency> dependencies = new ArrayList<Dependency>(
|
final List<Dependency> dependencies = new ArrayList<Dependency>(
|
||||||
engine.getDependencies());
|
engine.getDependencies());
|
||||||
@@ -199,8 +200,9 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This should gather information from leading docstrings, file comments, and assignments to __version__, __title__,
|
* This should gather information from leading docstrings, file comments,
|
||||||
* __summary__, __uri__, __url__, __home*page__, __author__, and their all caps equivalents.
|
* and assignments to __version__, __title__, __summary__, __uri__, __url__,
|
||||||
|
* __home*page__, __author__, and their all caps equivalents.
|
||||||
*
|
*
|
||||||
* @param dependency the dependency being analyzed
|
* @param dependency the dependency being analyzed
|
||||||
* @param file the file name to analyze
|
* @param file the file name to analyze
|
||||||
@@ -291,7 +293,8 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gather evidence from a Python source file using the given string assignment regex pattern.
|
* Gather evidence from a Python source file using the given string
|
||||||
|
* assignment regex pattern.
|
||||||
*
|
*
|
||||||
* @param pattern to scan contents with
|
* @param pattern to scan contents with
|
||||||
* @param contents of Python source file
|
* @param contents of Python source file
|
||||||
|
|||||||
@@ -61,8 +61,7 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
*/
|
*/
|
||||||
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_INFORMATION_COLLECTION;
|
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_INFORMATION_COLLECTION;
|
||||||
|
|
||||||
private static final FileFilter FILTER
|
private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames("Gemfile.lock").build();
|
||||||
= FileFilterBuilder.newInstance().addFilenames("Gemfile.lock").build();
|
|
||||||
public static final String NAME = "Name: ";
|
public static final String NAME = "Name: ";
|
||||||
public static final String VERSION = "Version: ";
|
public static final String VERSION = "Version: ";
|
||||||
public static final String ADVISORY = "Advisory: ";
|
public static final String ADVISORY = "Advisory: ";
|
||||||
@@ -81,7 +80,9 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
/**
|
/**
|
||||||
* Launch bundle-audit.
|
* Launch bundle-audit.
|
||||||
*
|
*
|
||||||
|
* @param folder directory that contains bundle audit
|
||||||
* @return a handle to the process
|
* @return a handle to the process
|
||||||
|
* @throws AnalysisException thrown when there is an issue launching bundle audit
|
||||||
*/
|
*/
|
||||||
private Process launchBundleAudit(File folder) throws AnalysisException {
|
private Process launchBundleAudit(File folder) throws AnalysisException {
|
||||||
if (!folder.isDirectory()) {
|
if (!folder.isDirectory()) {
|
||||||
@@ -131,7 +132,7 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
throw ae;
|
throw ae;
|
||||||
}
|
}
|
||||||
|
|
||||||
int exitValue = process.waitFor();
|
final int exitValue = process.waitFor();
|
||||||
if (0 == exitValue) {
|
if (0 == exitValue) {
|
||||||
LOGGER.warn("Unexpected exit code from bundle-audit process. Disabling {}: {}", ANALYZER_NAME, exitValue);
|
LOGGER.warn("Unexpected exit code from bundle-audit process. Disabling {}: {}", ANALYZER_NAME, exitValue);
|
||||||
setEnabled(false);
|
setEnabled(false);
|
||||||
@@ -236,7 +237,7 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
try {
|
try {
|
||||||
errReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8"));
|
errReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8"));
|
||||||
while (errReader.ready()) {
|
while (errReader.ready()) {
|
||||||
String error = errReader.readLine();
|
final String error = errReader.readLine();
|
||||||
LOGGER.warn(error);
|
LOGGER.warn(error);
|
||||||
}
|
}
|
||||||
rdr = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));
|
rdr = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));
|
||||||
@@ -284,7 +285,7 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
dependency = map.get(gem);
|
dependency = map.get(gem);
|
||||||
LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
|
LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
|
||||||
} else if (nextLine.startsWith(VERSION)) {
|
} else if (nextLine.startsWith(VERSION)) {
|
||||||
vulnerability = createVulnerability(parentName, dependency, vulnerability, gem, nextLine);
|
vulnerability = createVulnerability(parentName, dependency, gem, nextLine);
|
||||||
} else if (nextLine.startsWith(ADVISORY)) {
|
} else if (nextLine.startsWith(ADVISORY)) {
|
||||||
setVulnerabilityName(parentName, dependency, vulnerability, nextLine);
|
setVulnerabilityName(parentName, dependency, vulnerability, nextLine);
|
||||||
} else if (nextLine.startsWith(CRITICALITY)) {
|
} else if (nextLine.startsWith(CRITICALITY)) {
|
||||||
@@ -318,7 +319,7 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
private void addReferenceToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) {
|
private void addReferenceToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) {
|
||||||
final String url = nextLine.substring(("URL: ").length());
|
final String url = nextLine.substring(("URL: ").length());
|
||||||
if (null != vulnerability) {
|
if (null != vulnerability) {
|
||||||
Reference ref = new Reference();
|
final Reference ref = new Reference();
|
||||||
ref.setName(vulnerability.getName());
|
ref.setName(vulnerability.getName());
|
||||||
ref.setSource("bundle-audit");
|
ref.setSource("bundle-audit");
|
||||||
ref.setUrl(url);
|
ref.setUrl(url);
|
||||||
@@ -351,7 +352,8 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
|
LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Vulnerability createVulnerability(String parentName, Dependency dependency, Vulnerability vulnerability, String gem, String nextLine) {
|
private Vulnerability createVulnerability(String parentName, Dependency dependency, String gem, String nextLine) {
|
||||||
|
Vulnerability vulnerability = null;
|
||||||
if (null != dependency) {
|
if (null != dependency) {
|
||||||
final String version = nextLine.substring(VERSION.length());
|
final String version = nextLine.substring(VERSION.length());
|
||||||
dependency.getVersionEvidence().addEvidence(
|
dependency.getVersionEvidence().addEvidence(
|
||||||
|
|||||||
@@ -25,20 +25,23 @@ import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
|||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This analyzer accepts the fully resolved .gemspec created by the Ruby bundler (http://bundler.io)
|
* This analyzer accepts the fully resolved .gemspec created by the Ruby bundler
|
||||||
* for better evidence results. It also tries to resolve the dependency packagePath
|
* (http://bundler.io) for better evidence results. It also tries to resolve the
|
||||||
* to where the gem is actually installed. Then during {@link AnalysisPhase.PRE_FINDING_ANALYSIS}
|
* dependency packagePath to where the gem is actually installed. Then during {@link AnalysisPhase.PRE_FINDING_ANALYSIS}
|
||||||
* {@link DependencyBundlingAnalyzer} will merge two .gemspec dependencies together if
|
* {@link DependencyBundlingAnalyzer} will merge two .gemspec dependencies
|
||||||
* <code>Dependency.getPackagePath()</code> are the same.
|
* together if <code>Dependency.getPackagePath()</code> are the same.
|
||||||
*
|
*
|
||||||
* Ruby bundler creates new .gemspec files under a folder called "specifications" at deploy time,
|
* Ruby bundler creates new .gemspec files under a folder called
|
||||||
* in addition to the original .gemspec files from source. The bundler generated
|
* "specifications" at deploy time, in addition to the original .gemspec files
|
||||||
* .gemspec files always contain fully resolved attributes thus provide more accurate
|
* from source. The bundler generated .gemspec files always contain fully
|
||||||
* evidences, whereas the original .gemspec from source often contain variables for attributes
|
* resolved attributes thus provide more accurate evidences, whereas the
|
||||||
* that can't be used for evidences.
|
* original .gemspec from source often contain variables for attributes that
|
||||||
|
* can't be used for evidences.
|
||||||
*
|
*
|
||||||
* Note this analyzer share the same {@link Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED} as
|
* Note this analyzer share the same
|
||||||
* {@link RubyGemspecAnalyzer}, so it will enabled/disabled with {@link RubyGemspecAnalyzer}.
|
* {@link Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED} as
|
||||||
|
* {@link RubyGemspecAnalyzer}, so it will enabled/disabled with
|
||||||
|
* {@link RubyGemspecAnalyzer}.
|
||||||
*
|
*
|
||||||
* @author Bianca Jiang (biancajiang@gmail.com)
|
* @author Bianca Jiang (biancajiang@gmail.com)
|
||||||
*/
|
*/
|
||||||
@@ -49,11 +52,15 @@ public class RubyBundlerAnalyzer extends RubyGemspecAnalyzer {
|
|||||||
*/
|
*/
|
||||||
private static final String ANALYZER_NAME = "Ruby Bundler Analyzer";
|
private static final String ANALYZER_NAME = "Ruby Bundler Analyzer";
|
||||||
|
|
||||||
//Folder name that contains .gemspec files created by "bundle install"
|
/**
|
||||||
private static final String SPECIFICATIONS = "specifications";
|
* Folder name that contains .gemspec files created by "bundle install"
|
||||||
|
*/
|
||||||
|
private static final String SPECIFICATIONS = "specifications";
|
||||||
|
|
||||||
//Folder name that contains the gems by "bundle install"
|
/**
|
||||||
private static final String GEMS = "gems";
|
* Folder name that contains the gems by "bundle install"
|
||||||
|
*/
|
||||||
|
private static final String GEMS = "gems";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of the analyzer.
|
* Returns the name of the analyzer.
|
||||||
@@ -66,61 +73,66 @@ public class RubyBundlerAnalyzer extends RubyGemspecAnalyzer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only accept *.gemspec files generated by "bundle install --deployment" under "specifications" folder.
|
* Only accept *.gemspec files generated by "bundle install --deployment"
|
||||||
|
* under "specifications" folder.
|
||||||
|
*
|
||||||
|
* @param pathname the path name to test
|
||||||
|
* @return true if the analyzer can process the given file; otherwise false
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(File pathname) {
|
public boolean accept(File pathname) {
|
||||||
|
|
||||||
boolean accepted = super.accept(pathname);
|
boolean accepted = super.accept(pathname);
|
||||||
if(accepted == true) {
|
if (accepted) {
|
||||||
File parentDir = pathname.getParentFile();
|
final File parentDir = pathname.getParentFile();
|
||||||
accepted = parentDir != null && parentDir.getName().equals(SPECIFICATIONS);
|
accepted = parentDir != null && parentDir.getName().equals(SPECIFICATIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
return accepted;
|
return accepted;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void analyzeFileType(Dependency dependency, Engine engine)
|
protected void analyzeFileType(Dependency dependency, Engine engine)
|
||||||
throws AnalysisException {
|
throws AnalysisException {
|
||||||
super.analyzeFileType(dependency, engine);
|
super.analyzeFileType(dependency, engine);
|
||||||
|
|
||||||
//find the corresponding gem folder for this .gemspec stub by "bundle install --deployment"
|
//find the corresponding gem folder for this .gemspec stub by "bundle install --deployment"
|
||||||
File gemspecFile = dependency.getActualFile();
|
final File gemspecFile = dependency.getActualFile();
|
||||||
String gemFileName = gemspecFile.getName();
|
final String gemFileName = gemspecFile.getName();
|
||||||
final String gemName = gemFileName.substring(0, gemFileName.lastIndexOf(".gemspec"));
|
final String gemName = gemFileName.substring(0, gemFileName.lastIndexOf(".gemspec"));
|
||||||
File specificationsDir = gemspecFile.getParentFile();
|
final File specificationsDir = gemspecFile.getParentFile();
|
||||||
if(specificationsDir != null && specificationsDir.getName().equals(SPECIFICATIONS) && specificationsDir.exists()) {
|
if (specificationsDir != null && specificationsDir.getName().equals(SPECIFICATIONS) && specificationsDir.exists()) {
|
||||||
File parentDir = specificationsDir.getParentFile();
|
final File parentDir = specificationsDir.getParentFile();
|
||||||
if(parentDir != null && parentDir.exists()) {
|
if (parentDir != null && parentDir.exists()) {
|
||||||
File gemsDir = new File(parentDir, GEMS);
|
final File gemsDir = new File(parentDir, GEMS);
|
||||||
if(gemsDir != null && gemsDir.exists()) {
|
if (gemsDir.exists()) {
|
||||||
File[] matchingFiles = gemsDir.listFiles(new FilenameFilter() {
|
final File[] matchingFiles = gemsDir.listFiles(new FilenameFilter() {
|
||||||
public boolean accept(File dir, String name) {
|
public boolean accept(File dir, String name) {
|
||||||
return name.equals(gemName);
|
return name.equals(gemName);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if(matchingFiles.length > 0) {
|
if (matchingFiles != null && matchingFiles.length > 0) {
|
||||||
String gemPath = matchingFiles[0].getAbsolutePath();
|
final String gemPath = matchingFiles[0].getAbsolutePath();
|
||||||
if(dependency.getActualFilePath().equals(dependency.getFilePath())) {
|
if (dependency.getActualFilePath().equals(dependency.getFilePath())) {
|
||||||
if(gemPath != null)
|
if (gemPath != null) {
|
||||||
dependency.setPackagePath(gemPath);
|
dependency.setPackagePath(gemPath);
|
||||||
} else {
|
}
|
||||||
//.gemspec's actualFilePath and filePath are different when it's from a compressed file
|
} else {
|
||||||
//in which case actualFilePath is the temp directory used by decompression.
|
//.gemspec's actualFilePath and filePath are different when it's from a compressed file
|
||||||
//packagePath should use the filePath of the identified gem file in "gems" folder
|
//in which case actualFilePath is the temp directory used by decompression.
|
||||||
File gemspecStub = new File(dependency.getFilePath());
|
//packagePath should use the filePath of the identified gem file in "gems" folder
|
||||||
File specDir = gemspecStub.getParentFile();
|
final File gemspecStub = new File(dependency.getFilePath());
|
||||||
if(specDir != null && specDir.getName().equals(SPECIFICATIONS)) {
|
final File specDir = gemspecStub.getParentFile();
|
||||||
File gemsDir2 = new File(specDir.getParentFile(), GEMS);
|
if (specDir != null && specDir.getName().equals(SPECIFICATIONS)) {
|
||||||
File packageDir = new File(gemsDir2, gemName);
|
final File gemsDir2 = new File(specDir.getParentFile(), GEMS);
|
||||||
dependency.setPackagePath(packageDir.getAbsolutePath());
|
final File packageDir = new File(gemsDir2, gemName);
|
||||||
}
|
dependency.setPackagePath(packageDir.getAbsolutePath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,15 +34,22 @@ import org.owasp.dependencycheck.dependency.Dependency;
|
|||||||
import org.owasp.dependencycheck.dependency.EvidenceCollection;
|
import org.owasp.dependencycheck.dependency.EvidenceCollection;
|
||||||
import org.owasp.dependencycheck.utils.FileFilterBuilder;
|
import org.owasp.dependencycheck.utils.FileFilterBuilder;
|
||||||
import org.owasp.dependencycheck.utils.Settings;
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to analyze Ruby Gem specifications and collect information that can be used to determine the associated CPE. Regular
|
* Used to analyze Ruby Gem specifications and collect information that can be
|
||||||
* expressions are used to parse the well-defined Ruby syntax that forms the specification.
|
* used to determine the associated CPE. Regular expressions are used to parse
|
||||||
|
* the well-defined Ruby syntax that forms the specification.
|
||||||
*
|
*
|
||||||
* @author Dale Visser
|
* @author Dale Visser
|
||||||
*/
|
*/
|
||||||
public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
|
public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logger.
|
||||||
|
*/
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(RubyGemspecAnalyzer.class);
|
||||||
/**
|
/**
|
||||||
* The name of the analyzer.
|
* The name of the analyzer.
|
||||||
*/
|
*/
|
||||||
@@ -53,13 +60,22 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
*/
|
*/
|
||||||
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
|
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The gemspec file extension.
|
||||||
|
*/
|
||||||
private static final String GEMSPEC = "gemspec";
|
private static final String GEMSPEC = "gemspec";
|
||||||
|
|
||||||
private static final FileFilter FILTER
|
/**
|
||||||
= FileFilterBuilder.newInstance().addExtensions(GEMSPEC).build();
|
* The file filter containing the list of file extensions that can be
|
||||||
//TODO: support Rakefile
|
* analyzed.
|
||||||
//= FileFilterBuilder.newInstance().addExtensions(GEMSPEC).addFilenames("Rakefile").build();
|
*/
|
||||||
|
private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(GEMSPEC).build();
|
||||||
|
//TODO: support Rakefile
|
||||||
|
//= FileFilterBuilder.newInstance().addExtensions(GEMSPEC).addFilenames("Rakefile").build();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the version file.
|
||||||
|
*/
|
||||||
private static final String VERSION_FILE_NAME = "VERSION";
|
private static final String VERSION_FILE_NAME = "VERSION";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -96,7 +112,8 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the key used in the properties file to reference the analyzer's enabled property.
|
* Returns the key used in the properties file to reference the analyzer's
|
||||||
|
* enabled property.
|
||||||
*
|
*
|
||||||
* @return the analyzer's enabled property setting key
|
* @return the analyzer's enabled property setting key
|
||||||
*/
|
*/
|
||||||
@@ -108,8 +125,7 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
/**
|
/**
|
||||||
* The capture group #1 is the block variable.
|
* The capture group #1 is the block variable.
|
||||||
*/
|
*/
|
||||||
private static final Pattern GEMSPEC_BLOCK_INIT
|
private static final Pattern GEMSPEC_BLOCK_INIT = Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|");
|
||||||
= Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|");
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void analyzeFileType(Dependency dependency, Engine engine)
|
protected void analyzeFileType(Dependency dependency, Engine engine)
|
||||||
@@ -139,70 +155,89 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
addStringEvidence(vendor, contents, blockVariable, "homepage", "homepage", Confidence.HIGHEST);
|
addStringEvidence(vendor, contents, blockVariable, "homepage", "homepage", Confidence.HIGHEST);
|
||||||
addStringEvidence(vendor, contents, blockVariable, "license", "licen[cs]es?", Confidence.HIGHEST);
|
addStringEvidence(vendor, contents, blockVariable, "license", "licen[cs]es?", Confidence.HIGHEST);
|
||||||
|
|
||||||
String value = addStringEvidence(dependency.getVersionEvidence(), contents, blockVariable, "version", "version", Confidence.HIGHEST);
|
final String value = addStringEvidence(dependency.getVersionEvidence(), contents,
|
||||||
if(value.length() < 1)
|
blockVariable, "version", "version", Confidence.HIGHEST);
|
||||||
addEvidenceFromVersionFile(dependency.getActualFile(), dependency.getVersionEvidence());
|
if (value.length() < 1) {
|
||||||
|
addEvidenceFromVersionFile(dependency.getActualFile(), dependency.getVersionEvidence());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setPackagePath(dependency);
|
setPackagePath(dependency);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the specified evidence to the given evidence collection.
|
||||||
|
*
|
||||||
|
* @param evidences the collection to add the evidence to
|
||||||
|
* @param contents the evidence contents
|
||||||
|
* @param blockVariable the variable
|
||||||
|
* @param field the field
|
||||||
|
* @param fieldPattern the field pattern
|
||||||
|
* @param confidence the confidence of the evidence
|
||||||
|
* @return the evidence string value added
|
||||||
|
*/
|
||||||
private String addStringEvidence(EvidenceCollection evidences, String contents,
|
private String addStringEvidence(EvidenceCollection evidences, String contents,
|
||||||
String blockVariable, String field, String fieldPattern, Confidence confidence) {
|
String blockVariable, String field, String fieldPattern, Confidence confidence) {
|
||||||
String value = "";
|
String value = "";
|
||||||
|
|
||||||
//capture array value between [ ]
|
//capture array value between [ ]
|
||||||
final Matcher arrayMatcher = Pattern.compile(
|
final Matcher arrayMatcher = Pattern.compile(
|
||||||
String.format("\\s*?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents);
|
String.format("\\s*?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents);
|
||||||
if(arrayMatcher.find()) {
|
if (arrayMatcher.find()) {
|
||||||
String arrayValue = arrayMatcher.group(1);
|
final String arrayValue = arrayMatcher.group(1);
|
||||||
value = arrayValue.replaceAll("['\"]", "").trim(); //strip quotes
|
value = arrayValue.replaceAll("['\"]", "").trim(); //strip quotes
|
||||||
}
|
} else { //capture single value between quotes
|
||||||
//capture single value between quotes
|
final Matcher matcher = Pattern.compile(
|
||||||
else {
|
String.format("\\s*?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents);
|
||||||
final Matcher matcher = Pattern.compile(
|
if (matcher.find()) {
|
||||||
String.format("\\s*?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents);
|
value = matcher.group(2);
|
||||||
if (matcher.find()) {
|
}
|
||||||
value = matcher.group(2);
|
}
|
||||||
}
|
if (value.length() > 0) {
|
||||||
}
|
evidences.addEvidence(GEMSPEC, field, value, confidence);
|
||||||
if(value.length() > 0)
|
}
|
||||||
evidences.addEvidence(GEMSPEC, field, value, confidence);
|
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String addEvidenceFromVersionFile(File dependencyFile, EvidenceCollection versionEvidences) {
|
/**
|
||||||
String value = null;
|
* Adds evidence from the version file.
|
||||||
File parentDir = dependencyFile.getParentFile();
|
*
|
||||||
if(parentDir != null) {
|
* @param dependencyFile the dependency being analyzed
|
||||||
File[] matchingFiles = parentDir.listFiles(new FilenameFilter() {
|
* @param versionEvidences the version evidence
|
||||||
public boolean accept(File dir, String name) {
|
*/
|
||||||
return name.contains(VERSION_FILE_NAME);
|
private void addEvidenceFromVersionFile(File dependencyFile, EvidenceCollection versionEvidences) {
|
||||||
}
|
final File parentDir = dependencyFile.getParentFile();
|
||||||
});
|
if (parentDir != null) {
|
||||||
|
final File[] matchingFiles = parentDir.listFiles(new FilenameFilter() {
|
||||||
for(int i = 0; i < matchingFiles.length; i++) {
|
public boolean accept(File dir, String name) {
|
||||||
try {
|
return name.contains(VERSION_FILE_NAME);
|
||||||
List<String> lines = FileUtils.readLines(matchingFiles[i]);
|
}
|
||||||
if(lines.size() == 1) { //TODO other checking?
|
});
|
||||||
value = lines.get(0).trim();
|
for (File f : matchingFiles) {
|
||||||
versionEvidences.addEvidence(GEMSPEC, "version", value, Confidence.HIGH);
|
try {
|
||||||
}
|
final List<String> lines = FileUtils.readLines(f, Charset.defaultCharset());
|
||||||
|
if (lines.size() == 1) { //TODO other checking?
|
||||||
} catch (IOException e) {
|
final String value = lines.get(0).trim();
|
||||||
e.printStackTrace();
|
versionEvidences.addEvidence(GEMSPEC, "version", value, Confidence.HIGH);
|
||||||
}
|
}
|
||||||
}
|
} catch (IOException e) {
|
||||||
}
|
LOGGER.debug("Error reading gemspec", e);
|
||||||
|
}
|
||||||
return value;
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the package path on the dependency.
|
||||||
|
*
|
||||||
|
* @param dep the dependency to alter
|
||||||
|
*/
|
||||||
private void setPackagePath(Dependency dep) {
|
private void setPackagePath(Dependency dep) {
|
||||||
File file = new File(dep.getFilePath());
|
final File file = new File(dep.getFilePath());
|
||||||
String parent = file.getParent();
|
final String parent = file.getParent();
|
||||||
if(parent != null)
|
if (parent != null) {
|
||||||
dep.setPackagePath(parent);
|
dep.setPackagePath(parent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,9 +36,10 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A program dependency. This object is one of the core components within DependencyCheck. It is used to collect information about
|
* A program dependency. This object is one of the core components within
|
||||||
* the dependency in the form of evidence. The Evidence is then used to determine if there are any known, published,
|
* DependencyCheck. It is used to collect information about the dependency in
|
||||||
* vulnerabilities associated with the program dependency.
|
* the form of evidence. The Evidence is then used to determine if there are any
|
||||||
|
* known, published, vulnerabilities associated with the program dependency.
|
||||||
*
|
*
|
||||||
* @author Jeremy Long
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
@@ -73,16 +74,30 @@ public class Dependency implements Serializable, Comparable<Dependency> {
|
|||||||
*/
|
*/
|
||||||
private String fileName;
|
private String fileName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The package path.
|
||||||
|
*/
|
||||||
private String packagePath;
|
private String packagePath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the package path.
|
||||||
|
*
|
||||||
|
* @return the package path
|
||||||
|
*/
|
||||||
public String getPackagePath() {
|
public String getPackagePath() {
|
||||||
return packagePath;
|
return packagePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPackagePath(String packagePath) {
|
/**
|
||||||
this.packagePath = packagePath;
|
* Sets the package path.
|
||||||
}
|
*
|
||||||
|
* @param packagePath the package path
|
||||||
|
*/
|
||||||
|
public void setPackagePath(String packagePath) {
|
||||||
|
this.packagePath = packagePath;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The md5 hash of the dependency.
|
* The md5 hash of the dependency.
|
||||||
*/
|
*/
|
||||||
private String md5sum;
|
private String md5sum;
|
||||||
@@ -144,10 +159,12 @@ public class Dependency implements Serializable, Comparable<Dependency> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the file name of the dependency with the backslash escaped for use in JavaScript. This is a complete hack as I
|
* Returns the file name of the dependency with the backslash escaped for
|
||||||
* could not get the replace to work in the template itself.
|
* use in JavaScript. This is a complete hack as I could not get the replace
|
||||||
|
* to work in the template itself.
|
||||||
*
|
*
|
||||||
* @return the file name of the dependency with the backslash escaped for use in JavaScript
|
* @return the file name of the dependency with the backslash escaped for
|
||||||
|
* use in JavaScript
|
||||||
*/
|
*/
|
||||||
public String getFileNameForJavaScript() {
|
public String getFileNameForJavaScript() {
|
||||||
return this.fileName.replace("\\", "\\\\");
|
return this.fileName.replace("\\", "\\\\");
|
||||||
@@ -199,9 +216,9 @@ public class Dependency implements Serializable, Comparable<Dependency> {
|
|||||||
* @param filePath the file path of the dependency
|
* @param filePath the file path of the dependency
|
||||||
*/
|
*/
|
||||||
public void setFilePath(String filePath) {
|
public void setFilePath(String filePath) {
|
||||||
if(this.packagePath == null || this.packagePath.equals(this.filePath))
|
if (this.packagePath == null || this.packagePath.equals(this.filePath)) {
|
||||||
this.packagePath = filePath;
|
this.packagePath = filePath;
|
||||||
|
}
|
||||||
this.filePath = filePath;
|
this.filePath = filePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,7 +237,8 @@ public class Dependency implements Serializable, Comparable<Dependency> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the file name to display in reports; if no display file name has been set it will default to the actual file name.
|
* Returns the file name to display in reports; if no display file name has
|
||||||
|
* been set it will default to the actual file name.
|
||||||
*
|
*
|
||||||
* @return the file name to display
|
* @return the file name to display
|
||||||
*/
|
*/
|
||||||
@@ -235,8 +253,9 @@ public class Dependency implements Serializable, Comparable<Dependency> {
|
|||||||
* <p>
|
* <p>
|
||||||
* Gets the file path of the dependency.</p>
|
* Gets the file path of the dependency.</p>
|
||||||
* <p>
|
* <p>
|
||||||
* <b>NOTE:</b> This may not be the actual path of the file on disk. The actual path of the file on disk can be obtained via
|
* <b>NOTE:</b> This may not be the actual path of the file on disk. The
|
||||||
* the getActualFilePath().</p>
|
* actual path of the file on disk can be obtained via the
|
||||||
|
* getActualFilePath().</p>
|
||||||
*
|
*
|
||||||
* @return the file path of the dependency
|
* @return the file path of the dependency
|
||||||
*/
|
*/
|
||||||
@@ -299,7 +318,8 @@ public class Dependency implements Serializable, Comparable<Dependency> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an entry to the list of detected Identifiers for the dependency file.
|
* Adds an entry to the list of detected Identifiers for the dependency
|
||||||
|
* file.
|
||||||
*
|
*
|
||||||
* @param type the type of identifier (such as CPE)
|
* @param type the type of identifier (such as CPE)
|
||||||
* @param value the value of the identifier
|
* @param value the value of the identifier
|
||||||
@@ -311,7 +331,8 @@ public class Dependency implements Serializable, Comparable<Dependency> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an entry to the list of detected Identifiers for the dependency file.
|
* Adds an entry to the list of detected Identifiers for the dependency
|
||||||
|
* file.
|
||||||
*
|
*
|
||||||
* @param type the type of identifier (such as CPE)
|
* @param type the type of identifier (such as CPE)
|
||||||
* @param value the value of the identifier
|
* @param value the value of the identifier
|
||||||
@@ -362,7 +383,8 @@ public class Dependency implements Serializable, Comparable<Dependency> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an entry to the list of detected Identifiers for the dependency file.
|
* Adds an entry to the list of detected Identifiers for the dependency
|
||||||
|
* file.
|
||||||
*
|
*
|
||||||
* @param identifier the identifier to add
|
* @param identifier the identifier to add
|
||||||
*/
|
*/
|
||||||
@@ -594,8 +616,9 @@ public class Dependency implements Serializable, Comparable<Dependency> {
|
|||||||
private Set<Dependency> relatedDependencies = new TreeSet<Dependency>();
|
private Set<Dependency> relatedDependencies = new TreeSet<Dependency>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value of {@link #relatedDependencies}. This field is used to collect other dependencies which really represent the
|
* Get the value of {@link #relatedDependencies}. This field is used to
|
||||||
* same dependency, and may be presented as one item in reports.
|
* collect other dependencies which really represent the same dependency,
|
||||||
|
* and may be presented as one item in reports.
|
||||||
*
|
*
|
||||||
* @return the value of relatedDependencies
|
* @return the value of relatedDependencies
|
||||||
*/
|
*/
|
||||||
@@ -654,9 +677,11 @@ public class Dependency implements Serializable, Comparable<Dependency> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a related dependency. The internal collection is normally a {@link java.util.TreeSet}, which relies on
|
* Adds a related dependency. The internal collection is normally a
|
||||||
* {@link #compareTo(Dependency)}. A consequence of this is that if you attempt to add a dependency with the same file path
|
* {@link java.util.TreeSet}, which relies on
|
||||||
* (modulo character case) as one that is already in the collection, it won't get added.
|
* {@link #compareTo(Dependency)}. A consequence of this is that if you
|
||||||
|
* attempt to add a dependency with the same file path (modulo character
|
||||||
|
* case) as one that is already in the collection, it won't get added.
|
||||||
*
|
*
|
||||||
* @param dependency a reference to the related dependency
|
* @param dependency a reference to the related dependency
|
||||||
*/
|
*/
|
||||||
@@ -706,7 +731,8 @@ public class Dependency implements Serializable, Comparable<Dependency> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of the Comparable<Dependency> interface. The comparison is solely based on the file path.
|
* Implementation of the Comparable<Dependency> interface. The
|
||||||
|
* comparison is solely based on the file path.
|
||||||
*
|
*
|
||||||
* @param o a dependency to compare
|
* @param o a dependency to compare
|
||||||
* @return an integer representing the natural ordering
|
* @return an integer representing the natural ordering
|
||||||
@@ -776,12 +802,14 @@ public class Dependency implements Serializable, Comparable<Dependency> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard toString() implementation showing the filename, actualFilePath, and filePath.
|
* Standard toString() implementation showing the filename, actualFilePath,
|
||||||
|
* and filePath.
|
||||||
*
|
*
|
||||||
* @return the string representation of the file
|
* @return the string representation of the file
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Dependency{ fileName='" + fileName + "', actualFilePath='" + actualFilePath + "', filePath='" + filePath + "', packagePath='" + packagePath + "'}";
|
return "Dependency{ fileName='" + fileName + "', actualFilePath='" + actualFilePath
|
||||||
|
+ "', filePath='" + filePath + "', packagePath='" + packagePath + "'}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -272,17 +272,17 @@ public class Model {
|
|||||||
* @return the value of projectURL
|
* @return the value of projectURL
|
||||||
*/
|
*/
|
||||||
public String getProjectURL() {
|
public String getProjectURL() {
|
||||||
return projectURL;
|
return projectURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the value of projectURL.
|
* Set the value of projectURL.
|
||||||
*
|
*
|
||||||
* @param parentVersion new value of projectURL
|
* @param projectURL new value of projectURL
|
||||||
*/
|
*/
|
||||||
public void setProjectURL(String projectURL) {
|
public void setProjectURL(String projectURL) {
|
||||||
this.projectURL = projectURL;
|
this.projectURL = projectURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process the Maven properties file and interpolate all properties.
|
* Process the Maven properties file and interpolate all properties.
|
||||||
@@ -308,11 +308,14 @@ public class Model {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* A utility function that will interpolate strings based on values given in the properties file. It will also interpolate the
|
* A utility function that will interpolate strings based on values given in
|
||||||
* strings contained within the properties file so that properties can reference other properties.</p>
|
* the properties file. It will also interpolate the strings contained
|
||||||
|
* within the properties file so that properties can reference other
|
||||||
|
* properties.</p>
|
||||||
* <p>
|
* <p>
|
||||||
* <b>Note:</b> if there is no property found the reference will be removed. In other words, if the interpolated string will
|
* <b>Note:</b> if there is no property found the reference will be removed.
|
||||||
* be replaced with an empty string.
|
* In other words, if the interpolated string will be replaced with an empty
|
||||||
|
* string.
|
||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
* Example:</p>
|
* Example:</p>
|
||||||
@@ -329,7 +332,8 @@ public class Model {
|
|||||||
* </code>
|
* </code>
|
||||||
*
|
*
|
||||||
* @param text the string that contains references to properties.
|
* @param text the string that contains references to properties.
|
||||||
* @param properties a collection of properties that may be referenced within the text.
|
* @param properties a collection of properties that may be referenced
|
||||||
|
* within the text.
|
||||||
* @return the interpolated text.
|
* @return the interpolated text.
|
||||||
*/
|
*/
|
||||||
public static String interpolateString(String text, Properties properties) {
|
public static String interpolateString(String text, Properties properties) {
|
||||||
@@ -340,8 +344,9 @@ public class Model {
|
|||||||
return substitutor.replace(text);
|
return substitutor.replace(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class that can provide values from a Properties object to a StrSubstitutor.
|
* Utility class that can provide values from a Properties object to a
|
||||||
|
* StrSubstitutor.
|
||||||
*/
|
*/
|
||||||
private static class PropertyLookup extends StrLookup {
|
private static class PropertyLookup extends StrLookup {
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,6 @@
|
|||||||
^ \* See the License for the specific language governing permissions and\s*$
|
^ \* See the License for the specific language governing permissions and\s*$
|
||||||
^ \* limitations under the License\.\s*$
|
^ \* limitations under the License\.\s*$
|
||||||
^ \*\s*$
|
^ \*\s*$
|
||||||
^ \* Copyright \(c\) 201[0-9] (Jeremy Long|Steve Springett|The OWASP Foundation|Institute for Defense Analyses)\. All Rights Reserved\.\s*$
|
^ \* Copyright \(c\) 201[0-9] (Jeremy Long|Steve Springett|Bianca Jiang|The OWASP Foundation|Institute for Defense Analyses)\. All Rights Reserved\.\s*$
|
||||||
^ \*/\s*$
|
^ \*/\s*$
|
||||||
^package
|
^package
|
||||||
|
|||||||
Reference in New Issue
Block a user