mirror of
https://github.com/ysoftdevs/DependencyCheck.git
synced 2026-01-14 07:43:40 +01:00
checkstyle/findbugs corrections
This commit is contained in:
@@ -73,7 +73,7 @@ public class StaticLoggerBinder implements LoggerFactoryBinder {
|
||||
public static String REQUESTED_API_VERSION = "1.7.12"; // final
|
||||
//CSON: VisibilityModifier
|
||||
//CSON: StaticVariableName
|
||||
|
||||
|
||||
/**
|
||||
* The logger factory class string.
|
||||
*/
|
||||
|
||||
@@ -35,11 +35,14 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This analyzer ensures dependencies that should be grouped together, to remove excess noise from the report, are grouped. An
|
||||
* example would be Spring, Spring 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>
|
||||
* This analyzer ensures dependencies that should be grouped together, to remove
|
||||
* excess noise from the report, are grouped. An example would be Spring, Spring
|
||||
* 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>
|
||||
* 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
|
||||
*/
|
||||
@@ -92,12 +95,14 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
||||
//</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
|
||||
* likely related. The related dependencies are bundled into a single reportable item.
|
||||
* Analyzes a set of dependencies. If they have been found to have the same
|
||||
* 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 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
|
||||
public void analyze(Dependency ignore, Engine engine) throws AnalysisException {
|
||||
@@ -138,11 +143,11 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
||||
mergeDependencies(nextDependency, dependency, dependenciesToRemove);
|
||||
break; //since we merged into the next dependency - skip forward to the next in mainIterator
|
||||
}
|
||||
} else if ( isSameRubyGem(dependency, nextDependency) ) {
|
||||
Dependency main = getMainGemspecDependency(dependency, nextDependency);
|
||||
if (main == dependency) {
|
||||
mergeDependencies(dependency, nextDependency, dependenciesToRemove);
|
||||
} else {
|
||||
} else if (isSameRubyGem(dependency, nextDependency)) {
|
||||
final Dependency main = getMainGemspecDependency(dependency, nextDependency);
|
||||
if (main == dependency) {
|
||||
mergeDependencies(dependency, nextDependency, dependenciesToRemove);
|
||||
} else {
|
||||
mergeDependencies(nextDependency, dependency, dependenciesToRemove);
|
||||
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.
|
||||
*
|
||||
* @param dependency the main dependency
|
||||
* @param relatedDependency a collection of dependencies to be removed from 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
|
||||
* adds to this collection
|
||||
* @param relatedDependency a collection of dependencies to be removed from
|
||||
* 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 adds to this
|
||||
* collection
|
||||
*/
|
||||
private void mergeDependencies(final Dependency dependency, final Dependency relatedDependency, final Set<Dependency> dependenciesToRemove) {
|
||||
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
|
||||
* @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 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) {
|
||||
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 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) {
|
||||
if (dependency1 == null || dependency1.getIdentifiers() == null
|
||||
@@ -310,37 +321,53 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Bundling Ruby gems that are identified from different .gemspec files but denote the same package path.
|
||||
* This happens when Ruby bundler installs an app's dependencies by running "bundle install".
|
||||
* Bundling Ruby gems that are identified from different .gemspec files but
|
||||
* 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) {
|
||||
if (dependency1 == null || dependency2 == null ||
|
||||
!dependency1.getFileName().endsWith(".gemspec") ||
|
||||
!dependency2.getFileName().endsWith(".gemspec") ||
|
||||
dependency1.getPackagePath() == null ||
|
||||
dependency2.getPackagePath() == null) {
|
||||
if (dependency1 == null || dependency2 == null
|
||||
|| !dependency1.getFileName().endsWith(".gemspec")
|
||||
|| !dependency2.getFileName().endsWith(".gemspec")
|
||||
|| dependency1.getPackagePath() == null
|
||||
|| dependency2.getPackagePath() == null) {
|
||||
return false;
|
||||
}
|
||||
if (dependency1.getPackagePath().equalsIgnoreCase(dependency2.getPackagePath()))
|
||||
return true;
|
||||
if (dependency1.getPackagePath().equalsIgnoreCase(dependency2.getPackagePath())) {
|
||||
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.
|
||||
* If 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.
|
||||
* In this case, they should not be grouped.
|
||||
* Ruby gems installed by "bundle install" can have zero or more *.gemspec
|
||||
* files, all of which have the same packagePath and should be grouped. If
|
||||
* 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. 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) {
|
||||
if (isSameRubyGem(dependency1, dependency2)) {
|
||||
final File lFile = dependency1.getActualFile();
|
||||
File left = lFile.getParentFile();
|
||||
if (isSameRubyGem(dependency1, dependency2)) {
|
||||
final File lFile = dependency1.getActualFile();
|
||||
final File left = lFile.getParentFile();
|
||||
if (left != null && left.getName().equalsIgnoreCase("specifications")) {
|
||||
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
|
||||
* 'right' library.
|
||||
* This is likely a very broken attempt at determining if the 'left'
|
||||
* dependency is the 'core' library in comparison to the 'right' library.
|
||||
*
|
||||
* @param left the dependency to test
|
||||
* @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) {
|
||||
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 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) {
|
||||
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
|
||||
* should be removed.
|
||||
* Determines if the jar is shaded and the created pom.xml identified the
|
||||
* same CPE as the jar - if so, the pom.xml dependency should be removed.
|
||||
*
|
||||
* @param dependency a 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) {
|
||||
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
|
||||
* first path is smaller.
|
||||
* Determines which path is shortest; if path lengths are equal then we use
|
||||
* compareTo of the string method to determine if the first path is smaller.
|
||||
*
|
||||
* @param left the first 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) {
|
||||
final String leftPath = left.replace('\\', '/');
|
||||
|
||||
@@ -70,7 +70,7 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
|
||||
/**
|
||||
* 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__.pyc",
|
||||
"__init__.pyo",
|
||||
@@ -81,7 +81,8 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
|
||||
*
|
||||
* @param dependency the dependency to analyze.
|
||||
* @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
|
||||
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
|
||||
@@ -107,13 +108,6 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
|
||||
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)) {
|
||||
dependency.getProductEvidence().addEvidence("file", "name",
|
||||
fileName, Confidence.HIGH);
|
||||
|
||||
@@ -29,7 +29,6 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@@ -578,7 +577,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
addMatchingValues(classes, trimmedDescription, dependency.getProductEvidence());
|
||||
}
|
||||
|
||||
String projectURL = pom.getProjectURL();
|
||||
final String projectURL = pom.getProjectURL();
|
||||
if (projectURL != null && !projectURL.trim().isEmpty()) {
|
||||
dependency.getVendorEvidence().addEvidence("pom", "url", projectURL, Confidence.HIGHEST);
|
||||
}
|
||||
|
||||
@@ -39,7 +39,8 @@ import java.util.regex.Matcher;
|
||||
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
|
||||
*/
|
||||
@@ -166,7 +167,8 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
*
|
||||
* @param dependency the dependency being analyzed
|
||||
* @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
|
||||
protected void analyzeFileType(Dependency dependency, Engine engine)
|
||||
@@ -175,21 +177,20 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
final File parent = file.getParentFile();
|
||||
final String parentName = parent.getName();
|
||||
if (INIT_PY_FILTER.accept(file)) {
|
||||
//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"
|
||||
//see section "6.4 Packages" from https://docs.python.org/2/tutorial/modules.html;
|
||||
//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"
|
||||
//see section "6.4 Packages" from https://docs.python.org/2/tutorial/modules.html;
|
||||
dependency.setDisplayFileName(parentName + "/__init__.py");
|
||||
dependency.getProductEvidence().addEvidence(file.getName(),
|
||||
"PackageName", parentName, Confidence.HIGHEST);
|
||||
|
||||
|
||||
final File[] fileList = parent.listFiles(PY_FILTER);
|
||||
if (fileList != null) {
|
||||
for (final File sourceFile : fileList) {
|
||||
analyzeFileContents(dependency, sourceFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// copy, alter and set in case some other thread is iterating over
|
||||
final List<Dependency> dependencies = new ArrayList<Dependency>(
|
||||
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__,
|
||||
* __summary__, __uri__, __url__, __home*page__, __author__, and their all caps equivalents.
|
||||
* This should gather information from leading docstrings, file comments,
|
||||
* and assignments to __version__, __title__, __summary__, __uri__, __url__,
|
||||
* __home*page__, __author__, and their all caps equivalents.
|
||||
*
|
||||
* @param dependency the dependency being analyzed
|
||||
* @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 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 FileFilter FILTER
|
||||
= FileFilterBuilder.newInstance().addFilenames("Gemfile.lock").build();
|
||||
private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFilenames("Gemfile.lock").build();
|
||||
public static final String NAME = "Name: ";
|
||||
public static final String VERSION = "Version: ";
|
||||
public static final String ADVISORY = "Advisory: ";
|
||||
@@ -81,7 +80,9 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
/**
|
||||
* Launch bundle-audit.
|
||||
*
|
||||
* @param folder directory that contains bundle audit
|
||||
* @return a handle to the process
|
||||
* @throws AnalysisException thrown when there is an issue launching bundle audit
|
||||
*/
|
||||
private Process launchBundleAudit(File folder) throws AnalysisException {
|
||||
if (!folder.isDirectory()) {
|
||||
@@ -131,7 +132,7 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
throw ae;
|
||||
}
|
||||
|
||||
int exitValue = process.waitFor();
|
||||
final int exitValue = process.waitFor();
|
||||
if (0 == exitValue) {
|
||||
LOGGER.warn("Unexpected exit code from bundle-audit process. Disabling {}: {}", ANALYZER_NAME, exitValue);
|
||||
setEnabled(false);
|
||||
@@ -236,7 +237,7 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
try {
|
||||
errReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8"));
|
||||
while (errReader.ready()) {
|
||||
String error = errReader.readLine();
|
||||
final String error = errReader.readLine();
|
||||
LOGGER.warn(error);
|
||||
}
|
||||
rdr = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));
|
||||
@@ -284,7 +285,7 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
dependency = map.get(gem);
|
||||
LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine));
|
||||
} else if (nextLine.startsWith(VERSION)) {
|
||||
vulnerability = createVulnerability(parentName, dependency, vulnerability, gem, nextLine);
|
||||
vulnerability = createVulnerability(parentName, dependency, gem, nextLine);
|
||||
} else if (nextLine.startsWith(ADVISORY)) {
|
||||
setVulnerabilityName(parentName, dependency, vulnerability, nextLine);
|
||||
} else if (nextLine.startsWith(CRITICALITY)) {
|
||||
@@ -318,7 +319,7 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
private void addReferenceToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) {
|
||||
final String url = nextLine.substring(("URL: ").length());
|
||||
if (null != vulnerability) {
|
||||
Reference ref = new Reference();
|
||||
final Reference ref = new Reference();
|
||||
ref.setName(vulnerability.getName());
|
||||
ref.setSource("bundle-audit");
|
||||
ref.setUrl(url);
|
||||
@@ -351,7 +352,8 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
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) {
|
||||
final String version = nextLine.substring(VERSION.length());
|
||||
dependency.getVersionEvidence().addEvidence(
|
||||
|
||||
@@ -25,20 +25,23 @@ import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||
import org.owasp.dependencycheck.dependency.Dependency;
|
||||
|
||||
/**
|
||||
* This analyzer accepts the fully resolved .gemspec created by the Ruby bundler (http://bundler.io)
|
||||
* for better evidence results. It also tries to resolve the 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
|
||||
* <code>Dependency.getPackagePath()</code> are the same.
|
||||
*
|
||||
* Ruby bundler creates new .gemspec files under a folder called "specifications" at deploy time,
|
||||
* in addition to the original .gemspec files from source. The bundler generated
|
||||
* .gemspec files always contain fully resolved attributes thus provide more accurate
|
||||
* evidences, whereas the 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
|
||||
* {@link RubyGemspecAnalyzer}, so it will enabled/disabled with {@link RubyGemspecAnalyzer}.
|
||||
* This analyzer accepts the fully resolved .gemspec created by the Ruby bundler
|
||||
* (http://bundler.io) for better evidence results. It also tries to resolve the
|
||||
* 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 <code>Dependency.getPackagePath()</code> are the same.
|
||||
*
|
||||
* Ruby bundler creates new .gemspec files under a folder called
|
||||
* "specifications" at deploy time, in addition to the original .gemspec files
|
||||
* from source. The bundler generated .gemspec files always contain fully
|
||||
* resolved attributes thus provide more accurate evidences, whereas the
|
||||
* 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
|
||||
* {@link RubyGemspecAnalyzer}, so it will enabled/disabled with
|
||||
* {@link RubyGemspecAnalyzer}.
|
||||
*
|
||||
* @author Bianca Jiang (biancajiang@gmail.com)
|
||||
*/
|
||||
@@ -48,12 +51,16 @@ public class RubyBundlerAnalyzer extends RubyGemspecAnalyzer {
|
||||
* The name of the 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 the gems by "bundle install"
|
||||
private static final String GEMS = "gems";
|
||||
|
||||
/**
|
||||
* 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";
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
|
||||
|
||||
boolean accepted = super.accept(pathname);
|
||||
if(accepted == true) {
|
||||
File parentDir = pathname.getParentFile();
|
||||
accepted = parentDir != null && parentDir.getName().equals(SPECIFICATIONS);
|
||||
if (accepted) {
|
||||
final File parentDir = pathname.getParentFile();
|
||||
accepted = parentDir != null && parentDir.getName().equals(SPECIFICATIONS);
|
||||
}
|
||||
|
||||
|
||||
return accepted;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@Override
|
||||
protected void analyzeFileType(Dependency dependency, Engine engine)
|
||||
throws AnalysisException {
|
||||
super.analyzeFileType(dependency, engine);
|
||||
|
||||
|
||||
//find the corresponding gem folder for this .gemspec stub by "bundle install --deployment"
|
||||
File gemspecFile = dependency.getActualFile();
|
||||
String gemFileName = gemspecFile.getName();
|
||||
final File gemspecFile = dependency.getActualFile();
|
||||
final String gemFileName = gemspecFile.getName();
|
||||
final String gemName = gemFileName.substring(0, gemFileName.lastIndexOf(".gemspec"));
|
||||
File specificationsDir = gemspecFile.getParentFile();
|
||||
if(specificationsDir != null && specificationsDir.getName().equals(SPECIFICATIONS) && specificationsDir.exists()) {
|
||||
File parentDir = specificationsDir.getParentFile();
|
||||
if(parentDir != null && parentDir.exists()) {
|
||||
File gemsDir = new File(parentDir, GEMS);
|
||||
if(gemsDir != null && gemsDir.exists()) {
|
||||
File[] matchingFiles = gemsDir.listFiles(new FilenameFilter() {
|
||||
public boolean accept(File dir, String name) {
|
||||
return name.equals(gemName);
|
||||
}
|
||||
});
|
||||
|
||||
if(matchingFiles.length > 0) {
|
||||
String gemPath = matchingFiles[0].getAbsolutePath();
|
||||
if(dependency.getActualFilePath().equals(dependency.getFilePath())) {
|
||||
if(gemPath != null)
|
||||
dependency.setPackagePath(gemPath);
|
||||
} else {
|
||||
//.gemspec's actualFilePath and filePath are different when it's from a compressed file
|
||||
//in which case actualFilePath is the temp directory used by decompression.
|
||||
//packagePath should use the filePath of the identified gem file in "gems" folder
|
||||
File gemspecStub = new File(dependency.getFilePath());
|
||||
File specDir = gemspecStub.getParentFile();
|
||||
if(specDir != null && specDir.getName().equals(SPECIFICATIONS)) {
|
||||
File gemsDir2 = new File(specDir.getParentFile(), GEMS);
|
||||
File packageDir = new File(gemsDir2, gemName);
|
||||
dependency.setPackagePath(packageDir.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
final File specificationsDir = gemspecFile.getParentFile();
|
||||
if (specificationsDir != null && specificationsDir.getName().equals(SPECIFICATIONS) && specificationsDir.exists()) {
|
||||
final File parentDir = specificationsDir.getParentFile();
|
||||
if (parentDir != null && parentDir.exists()) {
|
||||
final File gemsDir = new File(parentDir, GEMS);
|
||||
if (gemsDir.exists()) {
|
||||
final File[] matchingFiles = gemsDir.listFiles(new FilenameFilter() {
|
||||
public boolean accept(File dir, String name) {
|
||||
return name.equals(gemName);
|
||||
}
|
||||
});
|
||||
|
||||
if (matchingFiles != null && matchingFiles.length > 0) {
|
||||
final String gemPath = matchingFiles[0].getAbsolutePath();
|
||||
if (dependency.getActualFilePath().equals(dependency.getFilePath())) {
|
||||
if (gemPath != null) {
|
||||
dependency.setPackagePath(gemPath);
|
||||
}
|
||||
} else {
|
||||
//.gemspec's actualFilePath and filePath are different when it's from a compressed file
|
||||
//in which case actualFilePath is the temp directory used by decompression.
|
||||
//packagePath should use the filePath of the identified gem file in "gems" folder
|
||||
final File gemspecStub = new File(dependency.getFilePath());
|
||||
final File specDir = gemspecStub.getParentFile();
|
||||
if (specDir != null && specDir.getName().equals(SPECIFICATIONS)) {
|
||||
final File gemsDir2 = new File(specDir.getParentFile(), GEMS);
|
||||
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.utils.FileFilterBuilder;
|
||||
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
|
||||
* expressions are used to parse the well-defined Ruby syntax that forms the specification.
|
||||
* Used to analyze Ruby Gem specifications and collect information that can be
|
||||
* used to determine the associated CPE. Regular expressions are used to parse
|
||||
* the well-defined Ruby syntax that forms the specification.
|
||||
*
|
||||
* @author Dale Visser
|
||||
*/
|
||||
public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*/
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(RubyGemspecAnalyzer.class);
|
||||
/**
|
||||
* The name of the analyzer.
|
||||
*/
|
||||
@@ -53,13 +60,22 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
*/
|
||||
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
|
||||
|
||||
/**
|
||||
* The gemspec file extension.
|
||||
*/
|
||||
private static final String GEMSPEC = "gemspec";
|
||||
|
||||
private static final FileFilter FILTER
|
||||
= FileFilterBuilder.newInstance().addExtensions(GEMSPEC).build();
|
||||
//TODO: support Rakefile
|
||||
//= FileFilterBuilder.newInstance().addExtensions(GEMSPEC).addFilenames("Rakefile").build();
|
||||
/**
|
||||
* The file filter containing the list of file extensions that can be
|
||||
* analyzed.
|
||||
*/
|
||||
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";
|
||||
|
||||
/**
|
||||
@@ -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
|
||||
*/
|
||||
@@ -108,8 +125,7 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
/**
|
||||
* The capture group #1 is the block variable.
|
||||
*/
|
||||
private static final Pattern GEMSPEC_BLOCK_INIT
|
||||
= Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|");
|
||||
private static final Pattern GEMSPEC_BLOCK_INIT = Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|");
|
||||
|
||||
@Override
|
||||
protected void analyzeFileType(Dependency dependency, Engine engine)
|
||||
@@ -125,7 +141,7 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
if (matcher.find()) {
|
||||
contents = contents.substring(matcher.end());
|
||||
final String blockVariable = matcher.group(1);
|
||||
|
||||
|
||||
final EvidenceCollection vendor = dependency.getVendorEvidence();
|
||||
final EvidenceCollection product = dependency.getProductEvidence();
|
||||
final String name = addStringEvidence(product, contents, blockVariable, "name", "name", Confidence.HIGHEST);
|
||||
@@ -138,71 +154,90 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
addStringEvidence(vendor, contents, blockVariable, "email", "emails?", Confidence.MEDIUM);
|
||||
addStringEvidence(vendor, contents, blockVariable, "homepage", "homepage", Confidence.HIGHEST);
|
||||
addStringEvidence(vendor, contents, blockVariable, "license", "licen[cs]es?", Confidence.HIGHEST);
|
||||
|
||||
String value = addStringEvidence(dependency.getVersionEvidence(), contents, blockVariable, "version", "version", Confidence.HIGHEST);
|
||||
if(value.length() < 1)
|
||||
addEvidenceFromVersionFile(dependency.getActualFile(), dependency.getVersionEvidence());
|
||||
|
||||
final String value = addStringEvidence(dependency.getVersionEvidence(), contents,
|
||||
blockVariable, "version", "version", Confidence.HIGHEST);
|
||||
if (value.length() < 1) {
|
||||
addEvidenceFromVersionFile(dependency.getActualFile(), dependency.getVersionEvidence());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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,
|
||||
String blockVariable, String field, String fieldPattern, Confidence confidence) {
|
||||
String value = "";
|
||||
|
||||
//capture array value between [ ]
|
||||
final Matcher arrayMatcher = Pattern.compile(
|
||||
|
||||
//capture array value between [ ]
|
||||
final Matcher arrayMatcher = Pattern.compile(
|
||||
String.format("\\s*?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents);
|
||||
if(arrayMatcher.find()) {
|
||||
String arrayValue = arrayMatcher.group(1);
|
||||
value = arrayValue.replaceAll("['\"]", "").trim(); //strip quotes
|
||||
}
|
||||
//capture single value between quotes
|
||||
else {
|
||||
final Matcher matcher = Pattern.compile(
|
||||
String.format("\\s*?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents);
|
||||
if (matcher.find()) {
|
||||
value = matcher.group(2);
|
||||
}
|
||||
}
|
||||
if(value.length() > 0)
|
||||
evidences.addEvidence(GEMSPEC, field, value, confidence);
|
||||
|
||||
if (arrayMatcher.find()) {
|
||||
final String arrayValue = arrayMatcher.group(1);
|
||||
value = arrayValue.replaceAll("['\"]", "").trim(); //strip quotes
|
||||
} else { //capture single value between quotes
|
||||
final Matcher matcher = Pattern.compile(
|
||||
String.format("\\s*?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents);
|
||||
if (matcher.find()) {
|
||||
value = matcher.group(2);
|
||||
}
|
||||
}
|
||||
if (value.length() > 0) {
|
||||
evidences.addEvidence(GEMSPEC, field, value, confidence);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private String addEvidenceFromVersionFile(File dependencyFile, EvidenceCollection versionEvidences) {
|
||||
String value = null;
|
||||
File parentDir = dependencyFile.getParentFile();
|
||||
if(parentDir != null) {
|
||||
File[] matchingFiles = parentDir.listFiles(new FilenameFilter() {
|
||||
public boolean accept(File dir, String name) {
|
||||
return name.contains(VERSION_FILE_NAME);
|
||||
}
|
||||
});
|
||||
|
||||
for(int i = 0; i < matchingFiles.length; i++) {
|
||||
try {
|
||||
List<String> lines = FileUtils.readLines(matchingFiles[i]);
|
||||
if(lines.size() == 1) { //TODO other checking?
|
||||
value = lines.get(0).trim();
|
||||
versionEvidences.addEvidence(GEMSPEC, "version", value, Confidence.HIGH);
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
|
||||
/**
|
||||
* Adds evidence from the version file.
|
||||
*
|
||||
* @param dependencyFile the dependency being analyzed
|
||||
* @param versionEvidences the version evidence
|
||||
*/
|
||||
private void addEvidenceFromVersionFile(File dependencyFile, EvidenceCollection versionEvidences) {
|
||||
final File parentDir = dependencyFile.getParentFile();
|
||||
if (parentDir != null) {
|
||||
final File[] matchingFiles = parentDir.listFiles(new FilenameFilter() {
|
||||
public boolean accept(File dir, String name) {
|
||||
return name.contains(VERSION_FILE_NAME);
|
||||
}
|
||||
});
|
||||
for (File f : matchingFiles) {
|
||||
try {
|
||||
final List<String> lines = FileUtils.readLines(f, Charset.defaultCharset());
|
||||
if (lines.size() == 1) { //TODO other checking?
|
||||
final String value = lines.get(0).trim();
|
||||
versionEvidences.addEvidence(GEMSPEC, "version", value, Confidence.HIGH);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOGGER.debug("Error reading gemspec", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the package path on the dependency.
|
||||
*
|
||||
* @param dep the dependency to alter
|
||||
*/
|
||||
private void setPackagePath(Dependency dep) {
|
||||
File file = new File(dep.getFilePath());
|
||||
String parent = file.getParent();
|
||||
if(parent != null)
|
||||
dep.setPackagePath(parent);
|
||||
final File file = new File(dep.getFilePath());
|
||||
final String parent = file.getParent();
|
||||
if (parent != null) {
|
||||
dep.setPackagePath(parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,9 +36,10 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* A program dependency. This object is one of the core components within DependencyCheck. It is used to collect information about
|
||||
* the dependency in the form of evidence. The Evidence is then used to determine if there are any known, published,
|
||||
* vulnerabilities associated with the program dependency.
|
||||
* A program dependency. This object is one of the core components within
|
||||
* DependencyCheck. It is used to collect information about the dependency in
|
||||
* 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
|
||||
*/
|
||||
@@ -72,17 +73,31 @@ public class Dependency implements Serializable, Comparable<Dependency> {
|
||||
* The file name of the dependency.
|
||||
*/
|
||||
private String fileName;
|
||||
|
||||
|
||||
/**
|
||||
* The package path.
|
||||
*/
|
||||
private String packagePath;
|
||||
|
||||
/**
|
||||
* Returns the package path.
|
||||
*
|
||||
* @return the package path
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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
|
||||
* could not get the replace to work in the template itself.
|
||||
* Returns the file name of the dependency with the backslash escaped for
|
||||
* 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() {
|
||||
return this.fileName.replace("\\", "\\\\");
|
||||
@@ -199,9 +216,9 @@ public class Dependency implements Serializable, Comparable<Dependency> {
|
||||
* @param filePath the file path of the dependency
|
||||
*/
|
||||
public void setFilePath(String filePath) {
|
||||
if(this.packagePath == null || this.packagePath.equals(this.filePath))
|
||||
this.packagePath = filePath;
|
||||
|
||||
if (this.packagePath == null || this.packagePath.equals(this.filePath)) {
|
||||
this.packagePath = 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
|
||||
*/
|
||||
@@ -235,8 +253,9 @@ public class Dependency implements Serializable, Comparable<Dependency> {
|
||||
* <p>
|
||||
* Gets the file path of the dependency.</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
|
||||
* the getActualFilePath().</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 the
|
||||
* getActualFilePath().</p>
|
||||
*
|
||||
* @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 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 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
|
||||
*/
|
||||
@@ -594,8 +616,9 @@ public class Dependency implements Serializable, Comparable<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
|
||||
* same dependency, and may be presented as one item in reports.
|
||||
* Get the value of {@link #relatedDependencies}. This field is used to
|
||||
* collect other dependencies which really represent the same dependency,
|
||||
* and may be presented as one item in reports.
|
||||
*
|
||||
* @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
|
||||
* {@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.
|
||||
* Adds a related dependency. The internal collection is normally a
|
||||
* {@link java.util.TreeSet}, which relies on
|
||||
* {@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
|
||||
*/
|
||||
@@ -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
|
||||
* @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
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Dependency{ fileName='" + fileName + "', actualFilePath='" + actualFilePath + "', filePath='" + filePath + "', packagePath='" + packagePath + "'}";
|
||||
return "Dependency{ fileName='" + fileName + "', actualFilePath='" + actualFilePath
|
||||
+ "', filePath='" + filePath + "', packagePath='" + packagePath + "'}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ public class Model {
|
||||
public void addLicense(License license) {
|
||||
licenses.add(license);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The project URL.
|
||||
*/
|
||||
@@ -272,17 +272,17 @@ public class Model {
|
||||
* @return the value of projectURL
|
||||
*/
|
||||
public String getProjectURL() {
|
||||
return projectURL;
|
||||
}
|
||||
return projectURL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of projectURL.
|
||||
*
|
||||
* @param parentVersion new value of projectURL
|
||||
* @param projectURL new value of projectURL
|
||||
*/
|
||||
public void setProjectURL(String projectURL) {
|
||||
this.projectURL = projectURL;
|
||||
}
|
||||
public void setProjectURL(String projectURL) {
|
||||
this.projectURL = projectURL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the Maven properties file and interpolate all properties.
|
||||
@@ -308,11 +308,14 @@ public class Model {
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* A utility function that will interpolate strings based on values given in the properties file. It will also interpolate the
|
||||
* strings contained within the properties file so that properties can reference other properties.</p>
|
||||
* A utility function that will interpolate strings based on values given in
|
||||
* the properties file. It will also interpolate the strings contained
|
||||
* within the properties file so that properties can reference other
|
||||
* properties.</p>
|
||||
* <p>
|
||||
* <b>Note:</b> if there is no property found the reference will be removed. In other words, if the interpolated string will
|
||||
* be replaced with an empty string.
|
||||
* <b>Note:</b> if there is no property found the reference will be removed.
|
||||
* In other words, if the interpolated string will be replaced with an empty
|
||||
* string.
|
||||
* </p>
|
||||
* <p>
|
||||
* Example:</p>
|
||||
@@ -329,7 +332,8 @@ public class Model {
|
||||
* </code>
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
public static String interpolateString(String text, Properties properties) {
|
||||
@@ -340,8 +344,9 @@ public class Model {
|
||||
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 {
|
||||
|
||||
|
||||
@@ -13,6 +13,6 @@
|
||||
^ \* See the License for the specific language governing permissions and\s*$
|
||||
^ \* limitations under the License\.\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*$
|
||||
^package
|
||||
|
||||
Reference in New Issue
Block a user