changes to support Ant style paths to resolve issue #153

Former-commit-id: b1666d6652891c4b012457fd5de7f8230938fb45
This commit is contained in:
Jeremy Long
2014-11-05 06:20:15 -05:00
parent f8c913a3e8
commit da77727673
2 changed files with 97 additions and 17 deletions

View File

@@ -21,7 +21,11 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.cli.ParseException;
@@ -29,6 +33,7 @@ import org.owasp.dependencycheck.data.nvdcve.CveDB;
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.org.apache.tools.ant.DirectoryScanner;
import org.owasp.dependencycheck.reporting.ReportGenerator;
import org.owasp.dependencycheck.utils.LogUtils;
import org.owasp.dependencycheck.utils.Settings;
@@ -92,7 +97,11 @@ public class App {
cli.printVersionInfo();
} else if (cli.isRunScan()) {
populateSettings(cli);
runScan(cli.getReportDirectory(), cli.getReportFormat(), cli.getApplicationName(), cli.getScanFiles());
try {
runScan(cli.getReportDirectory(), cli.getReportFormat(), cli.getApplicationName(), cli.getScanFiles(), cli.getExcludeList());
} catch (InvalidScanPathException ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, "An invalid scan path was detected; unable to scan '//*' paths");
}
} else {
cli.printHelp();
}
@@ -105,18 +114,69 @@ public class App {
* @param outputFormat the output format of the report
* @param applicationName the application name for the report
* @param files the files/directories to scan
* @param files the patterns for files/directories to exclude
*/
private void runScan(String reportDirectory, String outputFormat, String applicationName, String[] files) {
Engine scanner = null;
private void runScan(String reportDirectory, String outputFormat, String applicationName, String[] files,
String[] excludes) throws InvalidScanPathException {
Engine engine = null;
try {
scanner = new Engine();
for (String file : files) {
scanner.scan(file);
engine = new Engine();
List<String> antStylePaths = new ArrayList<String>();
if (excludes == null || excludes.length == 0) {
for (String file : files) {
if (file.contains("*") || file.contains("?")) {
antStylePaths.add(file);
} else {
engine.scan(file);
}
}
} else {
antStylePaths = Arrays.asList(files);
}
scanner.analyzeDependencies();
final List<Dependency> dependencies = scanner.getDependencies();
Set<File> paths = new HashSet<File>();
for (String file : antStylePaths) {
DirectoryScanner scanner = new DirectoryScanner();
String include = file.replace('\\', '/');
File baseDir;
if (include.startsWith("//")) {
throw new InvalidScanPathException("Unable to scan paths specified by //");
} else if (include.startsWith("./")) {
baseDir = new File(".");
include = include.substring(2);
} else if (include.startsWith("/")) {
baseDir = new File("/");
include = include.substring(1);
} else if (include.contains("/")) {
final int pos = include.indexOf('/');
String tmp = include.substring(0, pos);
if (tmp.contains("*") || tmp.contains("?")) {
baseDir = new File(".");
} else {
baseDir = new File(tmp);
include = include.substring(pos + 1);
}
} else { //no path info - must just be a file in the working directory
baseDir = new File(".");
}
scanner.setBasedir(baseDir);
scanner.setIncludes(include);
if (excludes != null && excludes.length > 0) {
scanner.addExcludes(excludes);
}
scanner.scan();
if (scanner.getIncludedFilesCount() > 0) {
for (String s : scanner.getIncludedFiles()) {
File f = new File(baseDir, s);
paths.add(f);
}
}
}
engine.scan(paths);
engine.analyzeDependencies();
final List<Dependency> dependencies = engine.getDependencies();
DatabaseProperties prop = null;
CveDB cve = null;
try {
@@ -130,7 +190,7 @@ public class App {
cve.close();
}
}
final ReportGenerator report = new ReportGenerator(applicationName, dependencies, scanner.getAnalyzers(), prop);
final ReportGenerator report = new ReportGenerator(applicationName, dependencies, engine.getAnalyzers(), prop);
try {
report.generateReports(reportDirectory, outputFormat);
} catch (IOException ex) {
@@ -144,8 +204,8 @@ public class App {
LOGGER.log(Level.SEVERE, "Unable to connect to the dependency-check database; analysis has stopped");
LOGGER.log(Level.FINE, "", ex);
} finally {
if (scanner != null) {
scanner.cleanup();
if (engine != null) {
engine.cleanup();
}
}
}

View File

@@ -134,7 +134,7 @@ public final class CliParser {
* @throws FileNotFoundException is thrown if the path being validated does not exist.
*/
private void validatePathExists(String path, String argumentName) throws FileNotFoundException {
if (!path.contains("*.")) {
if (!path.contains("*") && !path.contains("?")) {
final File f = new File(path);
if (!f.exists()) {
isValid = false;
@@ -151,7 +151,6 @@ public final class CliParser {
*/
@SuppressWarnings("static-access")
private Options createCommandLineOptions() {
final Options options = new Options();
addStandardOptions(options);
addAdvancedOptions(options);
@@ -184,10 +183,15 @@ public final class CliParser {
.create(ARGUMENT.APP_NAME_SHORT);
final Option path = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.SCAN)
.withDescription("The path to scan - this option can be specified multiple times. To limit the scan"
+ " to specific file types *.[ext] can be added to the end of the path.")
.withDescription("The path to scan - this option can be specified multiple times. Ant style"
+ " paths are supported (e.g. path/**/*.jar).")
.create(ARGUMENT.SCAN_SHORT);
final Option excludes = OptionBuilder.withArgName("pattern").hasArg().withLongOpt(ARGUMENT.EXCLUDE)
.withDescription("Specify and exclusion pattern. This option can be specified multiple times"
+ " and it accepts Ant style excludsions.")
.create();
final Option props = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.PROP)
.withDescription("A property file to load.")
.create(ARGUMENT.PROP_SHORT);
@@ -212,7 +216,11 @@ public final class CliParser {
final OptionGroup og = new OptionGroup();
og.addOption(path);
final OptionGroup exog = new OptionGroup();
exog.addOption(excludes);
options.addOptionGroup(og)
.addOptionGroup(exog)
.addOption(out)
.addOption(outputFormat)
.addOption(appName)
@@ -479,7 +487,6 @@ public final class CliParser {
options,
"",
true);
}
/**
@@ -491,6 +498,15 @@ public final class CliParser {
return line.getOptionValues(ARGUMENT.SCAN);
}
/**
* Retrieves the list of excluded file patterns specified by the 'exclude' argument.
*
* @return the excluded file patterns
*/
public String[] getExcludeList() {
return line.getOptionValues(ARGUMENT.EXCLUDE);
}
/**
* Returns the directory to write the reports to specified on the command line.
*
@@ -877,5 +893,9 @@ public final class CliParser {
* The CLI argument name for setting extra extensions.
*/
public static final String ADDITIONAL_ZIP_EXTENSIONS = "zipExtensions";
/**
* Exclude path argument
*/
public static final String EXCLUDE = "exclude";
}
}