From 62b6bf9105c19fbe68a9ae1d2c2a48eac2944480 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 20 Apr 2013 13:11:01 -0400 Subject: [PATCH] Correctly implemented this analyzer (hopefully) Former-commit-id: d65b60ee5212f3a10cc146a7f2aff345fd93695b --- .../analyzer/DependencyBundlingAnalyzer.java | 91 ++++++++++++------- 1 file changed, 58 insertions(+), 33 deletions(-) diff --git a/src/main/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.java b/src/main/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.java index b1f98d8d5..75cdd3786 100644 --- a/src/main/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.java +++ b/src/main/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.java @@ -19,7 +19,9 @@ package org.owasp.dependencycheck.analyzer; import java.io.File; +import java.util.HashSet; import java.util.Iterator; +import java.util.ListIterator; import java.util.Set; import org.owasp.dependencycheck.Engine; import org.owasp.dependencycheck.dependency.Dependency; @@ -87,42 +89,68 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal public AnalysisPhase getAnalysisPhase() { return ANALYSIS_PHASE; } + /** - * The Post Analysis Action that will be set after analyzing a dependency. + * a flag indicating if this analyzer has run. This analyzer only runs once. */ - private PostAnalysisAction action; + private boolean analyzed = false; /** * 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 dependency the dependency being analyzed + * @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. */ - public void analyze(Dependency dependency, Engine engine) throws AnalysisException { - action = PostAnalysisAction.NOTHING; - if (dependency.getIdentifiers().size() > 0) { - for (Dependency dependencyToCheck : engine.getDependencies()) { - if (dependency.equals(dependencyToCheck)) { - return; - } - if (identifiersMatch(dependencyToCheck, dependency) - && hasSameBasePath(dependencyToCheck, dependency) - && isCore(dependency, dependencyToCheck)) { - //move this dependency to be a related dependency - action = PostAnalysisAction.REMOVE_DEPENDENCY; - dependencyToCheck.addRelatedDependency(dependency); - //move any "related dependencies" to the new "parent" dependency - final Iterator i = dependency.getRelatedDependencies().iterator(); - while (i.hasNext()) { - dependencyToCheck.addRelatedDependency(i.next()); - i.remove(); + public void analyze(Dependency ignore, Engine engine) throws AnalysisException { + if (!analyzed) { + analyzed = true; + Set dependenciesToRemove = new HashSet(); + ListIterator mainIterator = engine.getDependencies().listIterator(); + //for (Dependency dependencyToCheck : engine.getDependencies()) { + while (mainIterator.hasNext()) { + final Dependency dependency = mainIterator.next(); + System.out.println("START " + dependency.getFileName() + "----------------------"); + if (mainIterator.hasNext()) { + ListIterator subIterator = engine.getDependencies().listIterator(mainIterator.nextIndex()); + while (subIterator.hasNext()) { + final Dependency dependencyToCheck = subIterator.next(); + if (identifiersMatch(dependency, dependencyToCheck) + && hasSameBasePath(dependency, dependencyToCheck)) { + + if (isCore(dependency, dependencyToCheck)) { + dependency.addRelatedDependency(dependencyToCheck); + //move any "related dependencies" to the new "parent" dependency + final Iterator i = dependencyToCheck.getRelatedDependencies().iterator(); + while (i.hasNext()) { + dependency.addRelatedDependency(i.next()); + i.remove(); + } + dependenciesToRemove.add(dependencyToCheck); + } else { + if (isCore(dependencyToCheck, dependency)) { + dependencyToCheck.addRelatedDependency(dependency); + //move any "related dependencies" to the new "parent" dependency + final Iterator i = dependency.getRelatedDependencies().iterator(); + while (i.hasNext()) { + dependencyToCheck.addRelatedDependency(i.next()); + i.remove(); + } + dependenciesToRemove.add(dependency); + } + } + } } - return; } + System.out.println("END " + dependency.getFileName() + "----------------------"); + } + //removing dependencies here as ensuring correctness and avoiding ConcurrentUpdateExceptions + // was difficult because of the inner iterator. + for (Dependency d : dependenciesToRemove) { + engine.getDependencies().remove(d); } } } @@ -134,10 +162,13 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal * @return true if the identifiers in the two supplied dependencies are equal */ private boolean identifiersMatch(Dependency dependency1, Dependency dependency2) { + System.out.println("Checking Identifiers: " + dependency1.getFileName() + " and " + dependency2.getFileName()); if (dependency1 == null || dependency1.getIdentifiers() == null || dependency2 == null || dependency2.getIdentifiers() == null) { return false; } + System.out.println("Result = " + (dependency1.getIdentifiers().size() > 0 + && dependency2.getIdentifiers().equals(dependency1.getIdentifiers()))); return dependency1.getIdentifiers().size() > 0 && dependency2.getIdentifiers().equals(dependency1.getIdentifiers()); } @@ -175,31 +206,25 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal * considered the "core" version. */ private boolean isCore(Dependency left, Dependency right) { + System.out.println("Checking iscore: " + left.getFileName() + " and " + right.getFileName()); final String leftName = left.getFileName().toLowerCase(); final String rightName = right.getFileName().toLowerCase(); if (rightName.contains("core") && !leftName.contains("core")) { + System.out.println("core False 1"); return false; } else if (!rightName.contains("core") && leftName.contains("core")) { + System.out.println("core true 1"); return true; } else { //TODO should we be splitting the name on [-_(.\d)+] and seeing if the // parts are contained in the other side? if (leftName.length() > rightName.length()) { + System.out.println("core false 2"); return false; } + System.out.println("core true 2"); return true; } } - - /** - * Returns whether or not the dependency should be removed from the parent - * list of dependencies. - * - * @return a PostAnalysisAction of REMOVE or NOTHING - */ - @Override - public PostAnalysisAction getPostAnalysisAction() { - return action; - } }