changes for issue #630

This commit is contained in:
Jeremy Long
2016-12-18 11:58:58 -05:00
parent 32ebf6c8ed
commit d854917090

View File

@@ -84,7 +84,7 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer {
/**
* The phase that this analyzer is intended to run in.
*/
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_FINDING_ANALYSIS;
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.FINAL;
/**
* Returns the name of the analyzer.
@@ -162,6 +162,7 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer {
}
} else if (cpeIdentifiersMatch(dependency, nextDependency)
&& hasSameBasePath(dependency, nextDependency)
&& vulnCountMatches(dependency, nextDependency)
&& fileNameMatch(dependency, nextDependency)) {
if (isCore(dependency, nextDependency)) {
mergeDependencies(dependency, nextDependency, dependenciesToRemove);
@@ -169,20 +170,6 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer {
mergeDependencies(nextDependency, dependency, dependenciesToRemove);
break; //since we merged into the next dependency - skip forward to the next in mainIterator
}
} else if ((main = getMainGemspecDependency(dependency, nextDependency)) != null) {
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
}
} else if ((main = getMainSwiftDependency(dependency, nextDependency)) != null) {
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
}
}
}
}
@@ -224,7 +211,12 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer {
* @return a string representing the base path.
*/
private String getBaseRepoPath(final String path) {
int pos = path.indexOf("repository" + File.separator) + 11;
int pos;
if (path.contains("local-repo")) {
pos = path.indexOf("local-repo" + File.separator) + 11;
} else {
pos = path.indexOf("repository" + File.separator) + 11;
}
if (pos < 0) {
return path;
}
@@ -317,6 +309,19 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer {
return matches;
}
/**
* Returns true if the two dependencies have the same vulnerability count.
*
* @param dependency1 a dependency2 to compare
* @param dependency2 a dependency2 to compare
* @return true if the two dependencies have the same vulnerability count
*/
private boolean vulnCountMatches(Dependency dependency1, Dependency dependency2) {
return dependency1.getVulnerabilities() != null && dependency2.getVulnerabilities() != null
&& dependency1.getVulnerabilities().size() == dependency2.getVulnerabilities().size();
}
/**
* Determines if the two dependencies have the same base path.
*
@@ -341,7 +346,7 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer {
return true;
}
if (left.matches(".*[/\\\\]repository[/\\\\].*") && right.matches(".*[/\\\\]repository[/\\\\].*")) {
if (left.matches(".*[/\\\\](repository|local-repo)[/\\\\].*") && right.matches(".*[/\\\\](repository|local-repo)[/\\\\].*")) {
left = getBaseRepoPath(left);
right = getBaseRepoPath(right);
}
@@ -357,96 +362,6 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer {
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
* 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) {
return false;
}
return dependency1.getPackagePath().equalsIgnoreCase(dependency2.getPackagePath());
}
/**
* 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();
final File left = lFile.getParentFile();
if (left != null && left.getName().equalsIgnoreCase("specifications")) {
return dependency1;
}
return dependency2;
}
return null;
}
/**
* Bundling same swift dependencies with the same packagePath but identified
* by different analyzers.
*
* @param dependency1 dependency to test
* @param dependency2 dependency to test
* @return <code>true</code> if the dependencies appear to be the same;
* otherwise <code>false</code>
*/
private boolean isSameSwiftPackage(Dependency dependency1, Dependency dependency2) {
if (dependency1 == null || dependency2 == null
|| (!dependency1.getFileName().endsWith(".podspec")
&& !dependency1.getFileName().equals("Package.swift"))
|| (!dependency2.getFileName().endsWith(".podspec")
&& !dependency2.getFileName().equals("Package.swift"))
|| dependency1.getPackagePath() == null
|| dependency2.getPackagePath() == null) {
return false;
}
return dependency1.getPackagePath().equalsIgnoreCase(dependency2.getPackagePath());
}
/**
* Determines which of the swift dependencies should be considered the
* primary.
*
* @param dependency1 the first swift dependency to compare
* @param dependency2 the second swift dependency to compare
* @return the primary swift dependency
*/
private Dependency getMainSwiftDependency(Dependency dependency1, Dependency dependency2) {
if (isSameSwiftPackage(dependency1, dependency2)) {
if (dependency1.getFileName().endsWith(".podspec")) {
return dependency1;
}
return dependency2;
}
return null;
}
/**
* This is likely a very broken attempt at determining if the 'left'
* dependency is the 'core' library in comparison to the 'right' library.
@@ -469,10 +384,6 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer {
|| !rightName.contains("core") && leftName.contains("core")
|| !rightName.contains("kernel") && leftName.contains("kernel")) {
returnVal = true;
// } else if (leftName.matches(".*struts2\\-core.*") && rightName.matches(".*xwork\\-core.*")) {
// returnVal = true;
// } else if (rightName.matches(".*struts2\\-core.*") && leftName.matches(".*xwork\\-core.*")) {
// returnVal = false;
} else {
/*
* considered splitting the names up and comparing the components,
@@ -577,4 +488,5 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer {
private boolean containedInWar(String filePath) {
return filePath == null ? false : filePath.matches(".*\\.(ear|war)[\\\\/].*");
}
}