mirror of
https://github.com/ysoftdevs/DependencyCheck.git
synced 2026-05-03 05:34:52 +02:00
Merge remote-tracking branch 'origin/master'
Former-commit-id: 9856f3f26b7c6e53d8497b5ef87d7a070abe4e06
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -7,6 +7,9 @@
|
|||||||
# Eclipse project files
|
# Eclipse project files
|
||||||
.classpath
|
.classpath
|
||||||
.project
|
.project
|
||||||
|
.settings
|
||||||
|
maven-eclipse.xml
|
||||||
|
.externalToolBuilders
|
||||||
# Netbeans configuration
|
# Netbeans configuration
|
||||||
nb-configuration.xml
|
nb-configuration.xml
|
||||||
/target/
|
/target/
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp</groupId>
|
<groupId>org.owasp</groupId>
|
||||||
<artifactId>dependency-check-parent</artifactId>
|
<artifactId>dependency-check-parent</artifactId>
|
||||||
<version>1.2.5</version>
|
<version>1.2.6-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>dependency-check-ant</artifactId>
|
<artifactId>dependency-check-ant</artifactId>
|
||||||
|
|||||||
@@ -47,16 +47,16 @@ types that they support are detected - so specifically disabling them may not
|
|||||||
be needed.
|
be needed.
|
||||||
|
|
||||||
Property | Description | Default Value
|
Property | Description | Default Value
|
||||||
------------------------|------------------------------------|------------------
|
------------------------|---------------------------------------------------------------------------|------------------
|
||||||
archiveAnalyzerEnabled | Sets whether the Archive Analyzer will be used. | true
|
archiveAnalyzerEnabled | Sets whether the Archive Analyzer will be used. | true
|
||||||
zipExtensions | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. |
|
zipExtensions | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. |
|
||||||
jarAnalyzer | Sets whether Jar Analyzer will be used. | true
|
jarAnalyzer | Sets whether Jar Analyzer will be used. | true
|
||||||
nexusAnalyzerEnabled | Sets whether Nexus Analyzer will be used. | true
|
nexusAnalyzerEnabled | Sets whether Nexus Analyzer will be used. | true
|
||||||
nexusUrl | Defines the Nexus URL. | https://repository.sonatype.org/service/local/
|
nexusUrl | Defines the Nexus Pro URL. If not set the Nexus Analyzer will be disabled. |
|
||||||
nexusUsesProxy | Whether or not the defined proxy should be used when connecting to Nexus. | true
|
nexusUsesProxy | Whether or not the defined proxy should be used when connecting to Nexus. | true
|
||||||
nuspecAnalyzerEnabled | Sets whether or not the .NET Nuget Nuspec Analyzer will be used. | true
|
nuspecAnalyzerEnabled | Sets whether or not the .NET Nuget Nuspec Analyzer will be used. | true
|
||||||
assemblyAnalyzerEnabled | Sets whether or not the .NET Assembly Analyzer should be used. | true
|
assemblyAnalyzerEnabled | Sets whether or not the .NET Assembly Analyzer should be used. | true
|
||||||
pathToMono | The path to Mono for .NET assembly analysis on non-windows systems |
|
pathToMono | The path to Mono for .NET assembly analysis on non-windows systems. |
|
||||||
|
|
||||||
Advanced Configuration
|
Advanced Configuration
|
||||||
====================
|
====================
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp</groupId>
|
<groupId>org.owasp</groupId>
|
||||||
<artifactId>dependency-check-parent</artifactId>
|
<artifactId>dependency-check-parent</artifactId>
|
||||||
<version>1.2.5</version>
|
<version>1.2.6-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>dependency-check-cli</artifactId>
|
<artifactId>dependency-check-cli</artifactId>
|
||||||
|
|||||||
@@ -21,15 +21,19 @@ import java.io.File;
|
|||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import org.apache.commons.cli.ParseException;
|
import org.apache.commons.cli.ParseException;
|
||||||
import org.owasp.dependencycheck.cli.CliParser;
|
|
||||||
import org.owasp.dependencycheck.data.nvdcve.CveDB;
|
import org.owasp.dependencycheck.data.nvdcve.CveDB;
|
||||||
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
||||||
import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
|
import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
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.reporting.ReportGenerator;
|
||||||
import org.owasp.dependencycheck.utils.LogUtils;
|
import org.owasp.dependencycheck.utils.LogUtils;
|
||||||
import org.owasp.dependencycheck.utils.Settings;
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
@@ -93,7 +97,11 @@ public class App {
|
|||||||
cli.printVersionInfo();
|
cli.printVersionInfo();
|
||||||
} else if (cli.isRunScan()) {
|
} else if (cli.isRunScan()) {
|
||||||
populateSettings(cli);
|
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 {
|
} else {
|
||||||
cli.printHelp();
|
cli.printHelp();
|
||||||
}
|
}
|
||||||
@@ -106,18 +114,71 @@ public class App {
|
|||||||
* @param outputFormat the output format of the report
|
* @param outputFormat the output format of the report
|
||||||
* @param applicationName the application name for the report
|
* @param applicationName the application name for the report
|
||||||
* @param files the files/directories to scan
|
* @param files the files/directories to scan
|
||||||
|
* @param excludes the patterns for files/directories to exclude
|
||||||
|
*
|
||||||
|
* @throws InvalidScanPathException thrown if the path to scan starts with "//"
|
||||||
*/
|
*/
|
||||||
private void runScan(String reportDirectory, String outputFormat, String applicationName, String[] files) {
|
private void runScan(String reportDirectory, String outputFormat, String applicationName, String[] files,
|
||||||
Engine scanner = null;
|
String[] excludes) throws InvalidScanPathException {
|
||||||
|
Engine engine = null;
|
||||||
try {
|
try {
|
||||||
scanner = new Engine();
|
engine = new Engine();
|
||||||
|
List<String> antStylePaths = new ArrayList<String>();
|
||||||
|
if (excludes == null || excludes.length == 0) {
|
||||||
for (String file : files) {
|
for (String file : files) {
|
||||||
scanner.scan(file);
|
if (file.contains("*") || file.contains("?")) {
|
||||||
|
antStylePaths.add(file);
|
||||||
|
} else {
|
||||||
|
engine.scan(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
antStylePaths = Arrays.asList(files);
|
||||||
}
|
}
|
||||||
|
|
||||||
scanner.analyzeDependencies();
|
final Set<File> paths = new HashSet<File>();
|
||||||
final List<Dependency> dependencies = scanner.getDependencies();
|
for (String file : antStylePaths) {
|
||||||
|
final 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('/');
|
||||||
|
final 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()) {
|
||||||
|
final File f = new File(baseDir, s);
|
||||||
|
paths.add(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
engine.scan(paths);
|
||||||
|
|
||||||
|
engine.analyzeDependencies();
|
||||||
|
final List<Dependency> dependencies = engine.getDependencies();
|
||||||
DatabaseProperties prop = null;
|
DatabaseProperties prop = null;
|
||||||
CveDB cve = null;
|
CveDB cve = null;
|
||||||
try {
|
try {
|
||||||
@@ -131,7 +192,7 @@ public class App {
|
|||||||
cve.close();
|
cve.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final ReportGenerator report = new ReportGenerator(applicationName, dependencies, scanner.getAnalyzers(), prop);
|
final ReportGenerator report = new ReportGenerator(applicationName, dependencies, engine.getAnalyzers(), prop);
|
||||||
try {
|
try {
|
||||||
report.generateReports(reportDirectory, outputFormat);
|
report.generateReports(reportDirectory, outputFormat);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
@@ -145,8 +206,8 @@ public class App {
|
|||||||
LOGGER.log(Level.SEVERE, "Unable to connect to the dependency-check database; analysis has stopped");
|
LOGGER.log(Level.SEVERE, "Unable to connect to the dependency-check database; analysis has stopped");
|
||||||
LOGGER.log(Level.FINE, "", ex);
|
LOGGER.log(Level.FINE, "", ex);
|
||||||
} finally {
|
} finally {
|
||||||
if (scanner != null) {
|
if (engine != null) {
|
||||||
scanner.cleanup();
|
engine.cleanup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.cli;
|
package org.owasp.dependencycheck;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
@@ -134,14 +134,33 @@ public final class CliParser {
|
|||||||
* @throws FileNotFoundException is thrown if the path being validated does not exist.
|
* @throws FileNotFoundException is thrown if the path being validated does not exist.
|
||||||
*/
|
*/
|
||||||
private void validatePathExists(String path, String argumentName) throws FileNotFoundException {
|
private void validatePathExists(String path, String argumentName) throws FileNotFoundException {
|
||||||
if (!path.contains("*.")) {
|
if (path == null) {
|
||||||
|
isValid = false;
|
||||||
|
final String msg = String.format("Invalid '%s' argument: null", argumentName);
|
||||||
|
throw new FileNotFoundException(msg);
|
||||||
|
} else if (!path.contains("*") && !path.contains("?")) {
|
||||||
final File f = new File(path);
|
final File f = new File(path);
|
||||||
|
if ("o".equals(argumentName.substring(0, 1).toLowerCase()) && !"ALL".equals(this.getReportFormat().toUpperCase())) {
|
||||||
|
final String checkPath = path.toLowerCase();
|
||||||
|
if (checkPath.endsWith(".html") || checkPath.endsWith(".xml") || checkPath.endsWith(".htm")) {
|
||||||
|
if (!f.getParentFile().isDirectory()) {
|
||||||
|
isValid = false;
|
||||||
|
final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path);
|
||||||
|
throw new FileNotFoundException(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (!f.exists()) {
|
if (!f.exists()) {
|
||||||
isValid = false;
|
isValid = false;
|
||||||
final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path);
|
final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path);
|
||||||
throw new FileNotFoundException(msg);
|
throw new FileNotFoundException(msg);
|
||||||
}
|
}
|
||||||
} // else { // TODO add a validation for *.zip extensions rather then relying on the engine to validate it.
|
}
|
||||||
|
} else if (path.startsWith("//") || path.startsWith("\\\\")) {
|
||||||
|
isValid = false;
|
||||||
|
final String msg = String.format("Invalid '%s' argument: '%s'%nUnable to scan paths that start with '//'.", argumentName, path);
|
||||||
|
throw new FileNotFoundException(msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -151,7 +170,6 @@ public final class CliParser {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("static-access")
|
@SuppressWarnings("static-access")
|
||||||
private Options createCommandLineOptions() {
|
private Options createCommandLineOptions() {
|
||||||
|
|
||||||
final Options options = new Options();
|
final Options options = new Options();
|
||||||
addStandardOptions(options);
|
addStandardOptions(options);
|
||||||
addAdvancedOptions(options);
|
addAdvancedOptions(options);
|
||||||
@@ -184,16 +202,22 @@ public final class CliParser {
|
|||||||
.create(ARGUMENT.APP_NAME_SHORT);
|
.create(ARGUMENT.APP_NAME_SHORT);
|
||||||
|
|
||||||
final Option path = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.SCAN)
|
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"
|
.withDescription("The path to scan - this option can be specified multiple times. Ant style"
|
||||||
+ " to specific file types *.[ext] can be added to the end of the path.")
|
+ " paths are supported (e.g. path/**/*.jar).")
|
||||||
.create(ARGUMENT.SCAN_SHORT);
|
.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)
|
final Option props = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.PROP)
|
||||||
.withDescription("A property file to load.")
|
.withDescription("A property file to load.")
|
||||||
.create(ARGUMENT.PROP_SHORT);
|
.create(ARGUMENT.PROP_SHORT);
|
||||||
|
|
||||||
final Option out = OptionBuilder.withArgName("folder").hasArg().withLongOpt(ARGUMENT.OUT)
|
final Option out = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.OUT)
|
||||||
.withDescription("The folder to write reports to. This defaults to the current directory.")
|
.withDescription("The folder to write reports to. This defaults to the current directory. "
|
||||||
|
+ "It is possible to set this to a specific file name if the format argument is not set to ALL.")
|
||||||
.create(ARGUMENT.OUT_SHORT);
|
.create(ARGUMENT.OUT_SHORT);
|
||||||
|
|
||||||
final Option outputFormat = OptionBuilder.withArgName("format").hasArg().withLongOpt(ARGUMENT.OUTPUT_FORMAT)
|
final Option outputFormat = OptionBuilder.withArgName("format").hasArg().withLongOpt(ARGUMENT.OUTPUT_FORMAT)
|
||||||
@@ -212,7 +236,11 @@ public final class CliParser {
|
|||||||
final OptionGroup og = new OptionGroup();
|
final OptionGroup og = new OptionGroup();
|
||||||
og.addOption(path);
|
og.addOption(path);
|
||||||
|
|
||||||
|
final OptionGroup exog = new OptionGroup();
|
||||||
|
exog.addOption(excludes);
|
||||||
|
|
||||||
options.addOptionGroup(og)
|
options.addOptionGroup(og)
|
||||||
|
.addOptionGroup(exog)
|
||||||
.addOption(out)
|
.addOption(out)
|
||||||
.addOption(outputFormat)
|
.addOption(outputFormat)
|
||||||
.addOption(appName)
|
.addOption(appName)
|
||||||
@@ -297,7 +325,7 @@ public final class CliParser {
|
|||||||
.create();
|
.create();
|
||||||
|
|
||||||
final Option nexusUrl = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.NEXUS_URL)
|
final Option nexusUrl = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.NEXUS_URL)
|
||||||
.withDescription("The url to the Nexus Server.")
|
.withDescription("The url to the Nexus Pro Server. If not set the Nexus Analyzer will be disabled.")
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
final Option nexusUsesProxy = OptionBuilder.withArgName("true/false").hasArg().withLongOpt(ARGUMENT.NEXUS_USES_PROXY)
|
final Option nexusUsesProxy = OptionBuilder.withArgName("true/false").hasArg().withLongOpt(ARGUMENT.NEXUS_USES_PROXY)
|
||||||
@@ -479,7 +507,6 @@ public final class CliParser {
|
|||||||
options,
|
options,
|
||||||
"",
|
"",
|
||||||
true);
|
true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -491,6 +518,15 @@ public final class CliParser {
|
|||||||
return line.getOptionValues(ARGUMENT.SCAN);
|
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.
|
* Returns the directory to write the reports to specified on the command line.
|
||||||
*
|
*
|
||||||
@@ -877,5 +913,9 @@ public final class CliParser {
|
|||||||
* The CLI argument name for setting extra extensions.
|
* The CLI argument name for setting extra extensions.
|
||||||
*/
|
*/
|
||||||
public static final String ADDITIONAL_ZIP_EXTENSIONS = "zipExtensions";
|
public static final String ADDITIONAL_ZIP_EXTENSIONS = "zipExtensions";
|
||||||
|
/**
|
||||||
|
* Exclude path argument.
|
||||||
|
*/
|
||||||
|
public static final String EXCLUDE = "exclude";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 OWASP.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown if an invalid path is encountered.
|
||||||
|
*
|
||||||
|
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||||
|
*/
|
||||||
|
class InvalidScanPathException extends Exception {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new InvalidScanPathException.
|
||||||
|
*/
|
||||||
|
public InvalidScanPathException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new InvalidScanPathException.
|
||||||
|
*
|
||||||
|
* @param msg a message for the exception
|
||||||
|
*/
|
||||||
|
public InvalidScanPathException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new InvalidScanPathException.
|
||||||
|
*
|
||||||
|
* @param ex the cause of the exception
|
||||||
|
*/
|
||||||
|
public InvalidScanPathException(Throwable ex) {
|
||||||
|
super(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new InvalidScanPathException.
|
||||||
|
*
|
||||||
|
* @param msg a message for the exception
|
||||||
|
* @param ex the cause of the exception
|
||||||
|
*/
|
||||||
|
public InvalidScanPathException(String msg, Throwable ex) {
|
||||||
|
super(msg, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/**
|
|
||||||
* <html>
|
|
||||||
* <head>
|
|
||||||
* <title>org.owasp.dependencycheck.cli</title>
|
|
||||||
* </head>
|
|
||||||
* <body>
|
|
||||||
* Includes utility classes such as the CLI Parser,
|
|
||||||
* </body>
|
|
||||||
* </html>
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.owasp.dependencycheck.cli;
|
|
||||||
@@ -6,8 +6,9 @@ The following table lists the command line arguments:
|
|||||||
Short | Argument Name | Parameter | Description | Requirement
|
Short | Argument Name | Parameter | Description | Requirement
|
||||||
-------|-----------------------|-----------------|-------------|------------
|
-------|-----------------------|-----------------|-------------|------------
|
||||||
\-a | \-\-app | \<name\> | The name of the application being scanned. This is a required argument. | Required
|
\-a | \-\-app | \<name\> | The name of the application being scanned. This is a required argument. | Required
|
||||||
\-s | \-\-scan | \<path\> | The path to scan \- this option can be specified multiple times. It is also possible to specify specific file types that should be scanned by supplying a scan path of '[path]/[to]/[scan]/*.zip'. The wild card can only be used to denote any file-name with a specific extension. | Required
|
\-s | \-\-scan | \<path\> | The path to scan \- this option can be specified multiple times. It is also possible to specify Ant style paths (e.g. directory/**/*.jar). | Required
|
||||||
\-o | \-\-out | \<folder\> | The folder to write reports to. This defaults to the current directory. | Optional
|
| \-\-exclude | \<pattern\> | The path patterns to exclude from the scan \- this option can be specified multiple times. This accepts Ant style path patterns (e.g. **/exclude/**) . | Optional
|
||||||
|
\-o | \-\-out | \<path\> | The folder to write reports to. This defaults to the current directory. If the format is not set to ALL one could specify a specific file name. | Optional
|
||||||
\-f | \-\-format | \<format\> | The output format to write to (XML, HTML, VULN, ALL). The default is HTML. | Required
|
\-f | \-\-format | \<format\> | The output format to write to (XML, HTML, VULN, ALL). The default is HTML. | Required
|
||||||
\-l | \-\-log | \<file\> | The file path to write verbose logging information. | Optional
|
\-l | \-\-log | \<file\> | The file path to write verbose logging information. | Optional
|
||||||
\-n | \-\-noupdate | | Disables the automatic updating of the CPE data. | Optional
|
\-n | \-\-noupdate | | Disables the automatic updating of the CPE data. | Optional
|
||||||
@@ -19,13 +20,12 @@ Short | Argument Name | Parameter | Description | Requir
|
|||||||
Advanced Options
|
Advanced Options
|
||||||
================
|
================
|
||||||
Short | Argument Name | Parameter | Description | Default Value
|
Short | Argument Name | Parameter | Description | Default Value
|
||||||
-------|-----------------------|-----------------|-------------|---------------
|
-------|-----------------------|-----------------|-----------------------------------------------------------------------------|---------------
|
||||||
| \-\-disableArchive | | Sets whether the Archive Analyzer will be used. | false
|
| \-\-disableArchive | | Sets whether the Archive Analyzer will be used. | false
|
||||||
| \-\-zipExtensions | \<strings\> | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. |
|
| \-\-zipExtensions | \<strings\> | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. |
|
||||||
| \-\-disableJar | | Sets whether Jar Analyzer will be used. | false
|
| \-\-disableJar | | Sets whether Jar Analyzer will be used. | false
|
||||||
| \-\-disableNexus | | Sets whether Nexus Analyzer will be used. | false
|
| \-\-disableNexus | | Sets whether Nexus Analyzer will be used. | false
|
||||||
| \-\-disableNexus | | Disable the Nexus Analyzer. |
|
| \-\-nexus | \<url\> | The url to the Nexus Pro Server. If not set the Nexus Analyzer will be disabled. |
|
||||||
| \-\-nexus | \<url\> | The url to the Nexus Server. | https://repository.sonatype.org/service/local/
|
|
||||||
| \-\-nexusUsesProxy | \<true\|false\> | Whether or not the defined proxy should be used when connecting to Nexus. | true
|
| \-\-nexusUsesProxy | \<true\|false\> | Whether or not the defined proxy should be used when connecting to Nexus. | true
|
||||||
| \-\-disableNuspec | | Sets whether or not the .NET Nuget Nuspec Analyzer will be used. | false
|
| \-\-disableNuspec | | Sets whether or not the .NET Nuget Nuspec Analyzer will be used. | false
|
||||||
| \-\-disableAssembly | | Sets whether or not the .NET Assembly Analyzer should be used. | false
|
| \-\-disableAssembly | | Sets whether or not the .NET Assembly Analyzer should be used. | false
|
||||||
|
|||||||
@@ -15,8 +15,9 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.cli;
|
package org.owasp.dependencycheck;
|
||||||
|
|
||||||
|
import org.owasp.dependencycheck.CliParser;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
@@ -20,7 +20,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp</groupId>
|
<groupId>org.owasp</groupId>
|
||||||
<artifactId>dependency-check-parent</artifactId>
|
<artifactId>dependency-check-parent</artifactId>
|
||||||
<version>1.2.5</version>
|
<version>1.2.6-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>dependency-check-core</artifactId>
|
<artifactId>dependency-check-core</artifactId>
|
||||||
@@ -400,6 +400,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
|||||||
<version>3.1</version>
|
<version>3.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<showDeprecation>false</showDeprecation>
|
<showDeprecation>false</showDeprecation>
|
||||||
|
<compilerArgument>-Xlint:unchecked</compilerArgument>
|
||||||
<source>1.6</source>
|
<source>1.6</source>
|
||||||
<target>1.6</target>
|
<target>1.6</target>
|
||||||
</configuration>
|
</configuration>
|
||||||
@@ -464,50 +465,6 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
|||||||
<artifactId>velocity</artifactId>
|
<artifactId>velocity</artifactId>
|
||||||
<version>1.7</version>
|
<version>1.7</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.velocity</groupId>
|
|
||||||
<artifactId>velocity-tools</artifactId>
|
|
||||||
<version>2.0</version>
|
|
||||||
<!-- very limited use of the velocity-tools, not all of the dependencies are needed-->
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>commons-chain</groupId>
|
|
||||||
<artifactId>commons-chain</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>javax.servlet</groupId>
|
|
||||||
<artifactId>servlet-api</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>commons-validator</groupId>
|
|
||||||
<artifactId>commons-validator</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>dom4j</groupId>
|
|
||||||
<artifactId>dom4j</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>sslext</groupId>
|
|
||||||
<artifactId>sslext</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.apache.struts</groupId>
|
|
||||||
<artifactId>struts-core</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>antlr</groupId>
|
|
||||||
<artifactId>antlr</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.apache.struts</groupId>
|
|
||||||
<artifactId>struts-taglib</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.apache.struts</groupId>
|
|
||||||
<artifactId>struts-tiles</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.h2database</groupId>
|
<groupId>com.h2database</groupId>
|
||||||
<artifactId>h2</artifactId>
|
<artifactId>h2</artifactId>
|
||||||
@@ -751,6 +708,21 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
|||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.sun.jersey</groupId>
|
||||||
|
<artifactId>jersey-client</artifactId>
|
||||||
|
<version>1.11.1</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.sun.faces</groupId>
|
||||||
|
<artifactId>jsf-impl</artifactId>
|
||||||
|
<version>2.2.8-02</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</profile>
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
|
|||||||
@@ -62,11 +62,11 @@ public class Engine implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* A Map of analyzers grouped by Analysis phase.
|
* A Map of analyzers grouped by Analysis phase.
|
||||||
*/
|
*/
|
||||||
private transient final EnumMap<AnalysisPhase, List<Analyzer>> analyzers;
|
private final transient EnumMap<AnalysisPhase, List<Analyzer>> analyzers;
|
||||||
/**
|
/**
|
||||||
* A Map of analyzers grouped by Analysis phase.
|
* A Map of analyzers grouped by Analysis phase.
|
||||||
*/
|
*/
|
||||||
private transient final Set<FileTypeAnalyzer> fileTypeAnalyzers;
|
private final transient Set<FileTypeAnalyzer> fileTypeAnalyzers;
|
||||||
/**
|
/**
|
||||||
* The ClassLoader to use when dynamically loading Analyzer and Update services.
|
* The ClassLoader to use when dynamically loading Analyzer and Update services.
|
||||||
*/
|
*/
|
||||||
@@ -74,7 +74,7 @@ public class Engine implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* The Logger for use throughout the class.
|
* The Logger for use throughout the class.
|
||||||
*/
|
*/
|
||||||
private transient static final Logger LOGGER = Logger.getLogger(Engine.class.getName());
|
private static final transient Logger LOGGER = Logger.getLogger(Engine.class.getName());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Engine.
|
* Creates a new Engine.
|
||||||
@@ -168,142 +168,171 @@ public class Engine implements Serializable {
|
|||||||
* Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any
|
* Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any
|
||||||
* dependencies identified are added to the dependency collection.
|
* dependencies identified are added to the dependency collection.
|
||||||
*
|
*
|
||||||
* @since v0.3.2.5
|
* @param paths an array of paths to files or directories to be analyzed
|
||||||
|
* @return the list of dependencies scanned
|
||||||
*
|
*
|
||||||
* @param paths an array of paths to files or directories to be analyzed.
|
* @since v0.3.2.5
|
||||||
*/
|
*/
|
||||||
public void scan(String[] paths) {
|
public List<Dependency> scan(String[] paths) {
|
||||||
|
final List<Dependency> deps = new ArrayList<Dependency>();
|
||||||
for (String path : paths) {
|
for (String path : paths) {
|
||||||
final File file = new File(path);
|
final File file = new File(path);
|
||||||
scan(file);
|
final List<Dependency> d = scan(file);
|
||||||
|
if (d != null) {
|
||||||
|
deps.addAll(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return deps;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies
|
* Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies
|
||||||
* identified are added to the dependency collection.
|
* identified are added to the dependency collection.
|
||||||
*
|
*
|
||||||
* @param path the path to a file or directory to be analyzed.
|
* @param path the path to a file or directory to be analyzed
|
||||||
|
* @return the list of dependencies scanned
|
||||||
*/
|
*/
|
||||||
public void scan(String path) {
|
public List<Dependency> scan(String path) {
|
||||||
if (path.matches("^.*[\\/]\\*\\.[^\\/:*|?<>\"]+$")) {
|
|
||||||
final String[] parts = path.split("\\*\\.");
|
|
||||||
final String[] ext = new String[]{parts[parts.length - 1]};
|
|
||||||
final File dir = new File(path.substring(0, path.length() - ext[0].length() - 2));
|
|
||||||
if (dir.isDirectory()) {
|
|
||||||
final List<File> files = (List<File>) org.apache.commons.io.FileUtils.listFiles(dir, ext, true);
|
|
||||||
scan(files);
|
|
||||||
} else {
|
|
||||||
final String msg = String.format("Invalid file path provided to scan '%s'", path);
|
|
||||||
LOGGER.log(Level.SEVERE, msg);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
final File file = new File(path);
|
final File file = new File(path);
|
||||||
scan(file);
|
return scan(file);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any
|
* Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any
|
||||||
* dependencies identified are added to the dependency collection.
|
* dependencies identified are added to the dependency collection.
|
||||||
*
|
*
|
||||||
* @since v0.3.2.5
|
|
||||||
*
|
|
||||||
* @param files an array of paths to files or directories to be analyzed.
|
* @param files an array of paths to files or directories to be analyzed.
|
||||||
|
* @return the list of dependencies
|
||||||
|
*
|
||||||
|
* @since v0.3.2.5
|
||||||
*/
|
*/
|
||||||
public void scan(File[] files) {
|
public List<Dependency> scan(File[] files) {
|
||||||
|
final List<Dependency> deps = new ArrayList<Dependency>();
|
||||||
for (File file : files) {
|
for (File file : files) {
|
||||||
scan(file);
|
final List<Dependency> d = scan(file);
|
||||||
|
if (d != null) {
|
||||||
|
deps.addAll(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return deps;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scans a list of files or directories. If a directory is specified, it will be scanned recursively. Any
|
* Scans a list of files or directories. If a directory is specified, it will be scanned recursively. Any
|
||||||
* dependencies identified are added to the dependency collection.
|
* dependencies identified are added to the dependency collection.
|
||||||
*
|
*
|
||||||
* @since v0.3.2.5
|
* @param files a set of paths to files or directories to be analyzed
|
||||||
|
* @return the list of dependencies scanned
|
||||||
*
|
*
|
||||||
* @param files a set of paths to files or directories to be analyzed.
|
* @since v0.3.2.5
|
||||||
*/
|
*/
|
||||||
public void scan(Set<File> files) {
|
public List<Dependency> scan(Set<File> files) {
|
||||||
|
final List<Dependency> deps = new ArrayList<Dependency>();
|
||||||
for (File file : files) {
|
for (File file : files) {
|
||||||
scan(file);
|
final List<Dependency> d = scan(file);
|
||||||
|
if (d != null) {
|
||||||
|
deps.addAll(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return deps;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scans a list of files or directories. If a directory is specified, it will be scanned recursively. Any
|
* Scans a list of files or directories. If a directory is specified, it will be scanned recursively. Any
|
||||||
* dependencies identified are added to the dependency collection.
|
* dependencies identified are added to the dependency collection.
|
||||||
*
|
*
|
||||||
* @since v0.3.2.5
|
* @param files a set of paths to files or directories to be analyzed
|
||||||
|
* @return the list of dependencies scanned
|
||||||
*
|
*
|
||||||
* @param files a set of paths to files or directories to be analyzed.
|
* @since v0.3.2.5
|
||||||
*/
|
*/
|
||||||
public void scan(List<File> files) {
|
public List<Dependency> scan(List<File> files) {
|
||||||
|
final List<Dependency> deps = new ArrayList<Dependency>();
|
||||||
for (File file : files) {
|
for (File file : files) {
|
||||||
scan(file);
|
final List<Dependency> d = scan(file);
|
||||||
|
if (d != null) {
|
||||||
|
deps.addAll(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return deps;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies
|
* Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies
|
||||||
* identified are added to the dependency collection.
|
* identified are added to the dependency collection.
|
||||||
*
|
*
|
||||||
|
* @param file the path to a file or directory to be analyzed
|
||||||
|
* @return the list of dependencies scanned
|
||||||
|
*
|
||||||
* @since v0.3.2.4
|
* @since v0.3.2.4
|
||||||
*
|
*
|
||||||
* @param file the path to a file or directory to be analyzed.
|
|
||||||
*/
|
*/
|
||||||
public void scan(File file) {
|
public List<Dependency> scan(File file) {
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
if (file.isDirectory()) {
|
if (file.isDirectory()) {
|
||||||
scanDirectory(file);
|
return scanDirectory(file);
|
||||||
} else {
|
} else {
|
||||||
scanFile(file);
|
final Dependency d = scanFile(file);
|
||||||
|
if (d != null) {
|
||||||
|
final List<Dependency> deps = new ArrayList<Dependency>();
|
||||||
|
deps.add(d);
|
||||||
|
return deps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursively scans files and directories. Any dependencies identified are added to the dependency collection.
|
* Recursively scans files and directories. Any dependencies identified are added to the dependency collection.
|
||||||
*
|
*
|
||||||
* @param dir the directory to scan.
|
* @param dir the directory to scan
|
||||||
|
* @return the list of Dependency objects scanned
|
||||||
*/
|
*/
|
||||||
protected void scanDirectory(File dir) {
|
protected List<Dependency> scanDirectory(File dir) {
|
||||||
final File[] files = dir.listFiles();
|
final File[] files = dir.listFiles();
|
||||||
|
final List<Dependency> deps = new ArrayList<Dependency>();
|
||||||
if (files != null) {
|
if (files != null) {
|
||||||
for (File f : files) {
|
for (File f : files) {
|
||||||
if (f.isDirectory()) {
|
if (f.isDirectory()) {
|
||||||
scanDirectory(f);
|
final List<Dependency> d = scanDirectory(f);
|
||||||
|
if (d != null) {
|
||||||
|
deps.addAll(d);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
scanFile(f);
|
final Dependency d = scanFile(f);
|
||||||
|
deps.add(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return deps;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scans a specified file. If a dependency is identified it is added to the dependency collection.
|
* Scans a specified file. If a dependency is identified it is added to the dependency collection.
|
||||||
*
|
*
|
||||||
* @param file The file to scan.
|
* @param file The file to scan
|
||||||
|
* @return the scanned dependency
|
||||||
*/
|
*/
|
||||||
protected void scanFile(File file) {
|
protected Dependency scanFile(File file) {
|
||||||
if (!file.isFile()) {
|
if (!file.isFile()) {
|
||||||
final String msg = String.format("Path passed to scanFile(File) is not a file: %s. Skipping the file.", file.toString());
|
final String msg = String.format("Path passed to scanFile(File) is not a file: %s. Skipping the file.", file.toString());
|
||||||
LOGGER.log(Level.FINE, msg);
|
LOGGER.log(Level.FINE, msg);
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
final String fileName = file.getName();
|
final String fileName = file.getName();
|
||||||
final String extension = FileUtils.getFileExtension(fileName);
|
final String extension = FileUtils.getFileExtension(fileName);
|
||||||
|
Dependency dependency = null;
|
||||||
if (extension != null) {
|
if (extension != null) {
|
||||||
if (supportsExtension(extension)) {
|
if (supportsExtension(extension)) {
|
||||||
final Dependency dependency = new Dependency(file);
|
dependency = new Dependency(file);
|
||||||
dependencies.add(dependency);
|
dependencies.add(dependency);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final String msg = String.format("No file extension found on file '%s'. The file was not analyzed.",
|
final String msg = String.format("No file extension found on file '%s'. The file was not analyzed.", file.toString());
|
||||||
file.toString());
|
|
||||||
LOGGER.log(Level.FINEST, msg);
|
LOGGER.log(Level.FINEST, msg);
|
||||||
}
|
}
|
||||||
|
return dependency;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -439,8 +468,7 @@ public class Engine implements Serializable {
|
|||||||
} catch (UpdateException ex) {
|
} catch (UpdateException ex) {
|
||||||
LOGGER.log(Level.WARNING,
|
LOGGER.log(Level.WARNING,
|
||||||
"Unable to update Cached Web DataSource, using local data instead. Results may not include recent vulnerabilities.");
|
"Unable to update Cached Web DataSource, using local data instead. Results may not include recent vulnerabilities.");
|
||||||
LOGGER.log(Level.FINE,
|
LOGGER.log(Level.FINE, String.format("Unable to update details for %s", source.getClass().getName()), ex);
|
||||||
String.format("Unable to update details for %s", source.getClass().getName()), ex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
static {
|
static {
|
||||||
final String additionalZipExt = Settings.getString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS);
|
final String additionalZipExt = Settings.getString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS);
|
||||||
if (additionalZipExt != null) {
|
if (additionalZipExt != null) {
|
||||||
final HashSet ext = new HashSet<String>(Arrays.asList(additionalZipExt));
|
final HashSet<String> ext = new HashSet<String>(Arrays.asList(additionalZipExt));
|
||||||
ZIPPABLES.addAll(ext);
|
ZIPPABLES.addAll(ext);
|
||||||
}
|
}
|
||||||
EXTENSIONS.addAll(ZIPPABLES);
|
EXTENSIONS.addAll(ZIPPABLES);
|
||||||
@@ -186,7 +186,7 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
if (tempFileLocation != null && tempFileLocation.exists()) {
|
if (tempFileLocation != null && tempFileLocation.exists()) {
|
||||||
LOGGER.log(Level.FINE, "Attempting to delete temporary files");
|
LOGGER.log(Level.FINE, "Attempting to delete temporary files");
|
||||||
final boolean success = FileUtils.delete(tempFileLocation);
|
final boolean success = FileUtils.delete(tempFileLocation);
|
||||||
if (!success && tempFileLocation != null & tempFileLocation.exists()) {
|
if (!success && tempFileLocation != null && tempFileLocation.exists() && tempFileLocation.list().length > 0) {
|
||||||
LOGGER.log(Level.WARNING, "Failed to delete some temporary files, see the log for more details");
|
LOGGER.log(Level.WARNING, "Failed to delete some temporary files, see the log for more details");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -221,9 +221,8 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
final String displayPath = String.format("%s%s",
|
final String displayPath = String.format("%s%s",
|
||||||
dependency.getFilePath(),
|
dependency.getFilePath(),
|
||||||
d.getActualFilePath().substring(tmpDir.getAbsolutePath().length()));
|
d.getActualFilePath().substring(tmpDir.getAbsolutePath().length()));
|
||||||
final String displayName = String.format("%s%s%s",
|
final String displayName = String.format("%s: %s",
|
||||||
dependency.getFileName(),
|
dependency.getFileName(),
|
||||||
File.separator,
|
|
||||||
d.getFileName());
|
d.getFileName());
|
||||||
d.setFilePath(displayPath);
|
d.setFilePath(displayPath);
|
||||||
d.setFileName(displayName);
|
d.setFileName(displayName);
|
||||||
|
|||||||
@@ -188,7 +188,9 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
if (!vendors.isEmpty() && !products.isEmpty()) {
|
if (!vendors.isEmpty() && !products.isEmpty()) {
|
||||||
final List<IndexEntry> entries = searchCPE(vendors, products, dependency.getProductEvidence().getWeighting(),
|
final List<IndexEntry> entries = searchCPE(vendors, products, dependency.getProductEvidence().getWeighting(),
|
||||||
dependency.getVendorEvidence().getWeighting());
|
dependency.getVendorEvidence().getWeighting());
|
||||||
|
if (entries == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
boolean identifierAdded = false;
|
boolean identifierAdded = false;
|
||||||
for (IndexEntry e : entries) {
|
for (IndexEntry e : entries) {
|
||||||
if (verifyEntry(e, dependency)) {
|
if (verifyEntry(e, dependency)) {
|
||||||
@@ -250,20 +252,17 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
* @param vendorWeightings a list of strings to use to add weighting factors to the vendor field
|
* @param vendorWeightings a list of strings to use to add weighting factors to the vendor field
|
||||||
* @param productWeightings Adds a list of strings that will be used to add weighting factors to the product search
|
* @param productWeightings Adds a list of strings that will be used to add weighting factors to the product search
|
||||||
* @return a list of possible CPE values
|
* @return a list of possible CPE values
|
||||||
* @throws CorruptIndexException when the Lucene index is corrupt
|
|
||||||
* @throws IOException when the Lucene index is not found
|
|
||||||
* @throws ParseException when the generated query is not valid
|
|
||||||
*/
|
*/
|
||||||
protected List<IndexEntry> searchCPE(String vendor, String product,
|
protected List<IndexEntry> searchCPE(String vendor, String product,
|
||||||
Set<String> vendorWeightings, Set<String> productWeightings)
|
Set<String> vendorWeightings, Set<String> productWeightings) {
|
||||||
throws CorruptIndexException, IOException, ParseException {
|
|
||||||
final ArrayList<IndexEntry> ret = new ArrayList<IndexEntry>(MAX_QUERY_RESULTS);
|
final ArrayList<IndexEntry> ret = new ArrayList<IndexEntry>(MAX_QUERY_RESULTS);
|
||||||
|
|
||||||
final String searchString = buildSearch(vendor, product, vendorWeightings, productWeightings);
|
final String searchString = buildSearch(vendor, product, vendorWeightings, productWeightings);
|
||||||
if (searchString == null) {
|
if (searchString == null) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
final TopDocs docs = cpe.search(searchString, MAX_QUERY_RESULTS);
|
final TopDocs docs = cpe.search(searchString, MAX_QUERY_RESULTS);
|
||||||
for (ScoreDoc d : docs.scoreDocs) {
|
for (ScoreDoc d : docs.scoreDocs) {
|
||||||
if (d.score >= 0.08) {
|
if (d.score >= 0.08) {
|
||||||
@@ -285,6 +284,16 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
} catch (ParseException ex) {
|
||||||
|
final String msg = String.format("Unable to parse: %s", searchString);
|
||||||
|
LOGGER.log(Level.WARNING, "An error occured querying the CPE data. See the log for more details.");
|
||||||
|
LOGGER.log(Level.INFO, msg, ex);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
final String msg = String.format("IO Error with search string: %s", searchString);
|
||||||
|
LOGGER.log(Level.WARNING, "An error occured reading CPE data. See the log for more details.");
|
||||||
|
LOGGER.log(Level.INFO, msg, ex);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -489,10 +498,12 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
* @param dependency the Dependency being analyzed
|
* @param dependency the Dependency being analyzed
|
||||||
* @param vendor the vendor for the CPE being analyzed
|
* @param vendor the vendor for the CPE being analyzed
|
||||||
* @param product the product for the CPE being analyzed
|
* @param product the product for the CPE being analyzed
|
||||||
|
* @param currentConfidence the current confidence being used during analysis
|
||||||
* @return <code>true</code> if an identifier was added to the dependency; otherwise <code>false</code>
|
* @return <code>true</code> if an identifier was added to the dependency; otherwise <code>false</code>
|
||||||
* @throws UnsupportedEncodingException is thrown if UTF-8 is not supported
|
* @throws UnsupportedEncodingException is thrown if UTF-8 is not supported
|
||||||
*/
|
*/
|
||||||
private boolean determineIdentifiers(Dependency dependency, String vendor, String product, Confidence currentConfidence) throws UnsupportedEncodingException {
|
protected boolean determineIdentifiers(Dependency dependency, String vendor, String product,
|
||||||
|
Confidence currentConfidence) throws UnsupportedEncodingException {
|
||||||
final Set<VulnerableSoftware> cpes = cve.getCPEs(vendor, product);
|
final Set<VulnerableSoftware> cpes = cve.getCPEs(vendor, product);
|
||||||
DependencyVersion bestGuess = new DependencyVersion("-");
|
DependencyVersion bestGuess = new DependencyVersion("-");
|
||||||
Confidence bestGuessConf = null;
|
Confidence bestGuessConf = null;
|
||||||
|
|||||||
@@ -0,0 +1,167 @@
|
|||||||
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
|
import org.owasp.dependencycheck.data.nexus.MavenArtifact;
|
||||||
|
import org.owasp.dependencycheck.data.central.CentralSearch;
|
||||||
|
import org.owasp.dependencycheck.dependency.Confidence;
|
||||||
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
import org.owasp.dependencycheck.utils.InvalidSettingException;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by colezlaw on 10/9/14.
|
||||||
|
*/
|
||||||
|
public class CentralAnalyzer extends AbstractFileTypeAnalyzer {
|
||||||
|
/**
|
||||||
|
* The logger.
|
||||||
|
*/
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(CentralAnalyzer.class.getName());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the analyzer.
|
||||||
|
*/
|
||||||
|
private static final String ANALYZER_NAME = "Central Analyzer";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The phase in which this analyzer runs.
|
||||||
|
*/
|
||||||
|
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The types of files on which this will work.
|
||||||
|
*/
|
||||||
|
private static final Set<String> SUPPORTED_EXTENSIONS = newHashSet("jar");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The analyzer should be disabled if there are errors, so this is a flag
|
||||||
|
* to determine if such an error has occurred.
|
||||||
|
*/
|
||||||
|
protected boolean errorFlag = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The searcher itself.
|
||||||
|
*/
|
||||||
|
private CentralSearch searcher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether to enable this analyzer or not.
|
||||||
|
*
|
||||||
|
* @return whether the analyzer should be enabled
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
boolean retval = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (Settings.getBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED)) {
|
||||||
|
if (!Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED)
|
||||||
|
|| NexusAnalyzer.DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL))) {
|
||||||
|
LOGGER.info("Enabling the Central analyzer");
|
||||||
|
retval = true;
|
||||||
|
} else {
|
||||||
|
LOGGER.info("Nexus analyzer is enabled, disabling Central");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOGGER.info("Central analyzer disabled");
|
||||||
|
}
|
||||||
|
} catch (InvalidSettingException ise) {
|
||||||
|
LOGGER.warning("Invalid setting. Disabling the Central analyzer");
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the analyzer once before any analysis is performed.
|
||||||
|
*
|
||||||
|
* @throws Exception if there's an error during initalization
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void initializeFileTypeAnalyzer() throws Exception {
|
||||||
|
LOGGER.fine("Initializing Central analyzer");
|
||||||
|
LOGGER.fine(String.format("Central analyzer enabled: %s", isEnabled()));
|
||||||
|
if (isEnabled()) {
|
||||||
|
final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_CENTRAL_URL);
|
||||||
|
LOGGER.fine(String.format("Central Analyzer URL: %s", searchUrl));
|
||||||
|
searcher = new CentralSearch(new URL(searchUrl));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the analyzer's name.
|
||||||
|
*
|
||||||
|
* @return the name of the analyzer
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return ANALYZER_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the key used in the properties file to to reference the analyzer's enabled property.
|
||||||
|
*
|
||||||
|
* @return the analyzer's enabled property setting key.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getAnalyzerEnabledSettingKey() {
|
||||||
|
return Settings.KEYS.ANALYZER_CENTRAL_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the analysis phase under which the analyzer runs.
|
||||||
|
*
|
||||||
|
* @return the phase under which the analyzer runs
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AnalysisPhase getAnalysisPhase() {
|
||||||
|
return ANALYSIS_PHASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the extensions for which this Analyzer runs.
|
||||||
|
*
|
||||||
|
* @return the extensions for which this Analyzer runs
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Set<String> getSupportedExtensions() {
|
||||||
|
return SUPPORTED_EXTENSIONS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the analysis.
|
||||||
|
*
|
||||||
|
* @param dependency the dependency to analyze
|
||||||
|
* @param engine the engine
|
||||||
|
* @throws AnalysisException when there's an exception during analysis
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
|
if (errorFlag || !isEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
final List<MavenArtifact> mas = searcher.searchSha1(dependency.getSha1sum());
|
||||||
|
final Confidence confidence = mas.size() > 1 ? Confidence.HIGH : Confidence.HIGHEST;
|
||||||
|
for (MavenArtifact ma : mas) {
|
||||||
|
LOGGER.fine(String.format("Central analyzer found artifact (%s) for dependency (%s)", ma.toString(), dependency.getFileName()));
|
||||||
|
dependency.addAsEvidence("central", ma, confidence);
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException iae) {
|
||||||
|
LOGGER.info(String.format("invalid sha1-hash on %s", dependency.getFileName()));
|
||||||
|
} catch (FileNotFoundException fnfe) {
|
||||||
|
LOGGER.fine(String.format("Artifact not found in repository: '%s", dependency.getFileName()));
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
LOGGER.log(Level.FINE, "Could not connect to Central search", ioe);
|
||||||
|
errorFlag = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -112,7 +112,7 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
|||||||
while (subIterator.hasNext()) {
|
while (subIterator.hasNext()) {
|
||||||
final Dependency nextDependency = subIterator.next();
|
final Dependency nextDependency = subIterator.next();
|
||||||
if (hashesMatch(dependency, nextDependency)) {
|
if (hashesMatch(dependency, nextDependency)) {
|
||||||
if (isCore(dependency, nextDependency)) {
|
if (firstPathIsShortest(dependency.getFilePath(), nextDependency.getFilePath())) {
|
||||||
mergeDependencies(dependency, nextDependency, dependenciesToRemove);
|
mergeDependencies(dependency, nextDependency, dependenciesToRemove);
|
||||||
} else {
|
} else {
|
||||||
mergeDependencies(nextDependency, dependency, dependenciesToRemove);
|
mergeDependencies(nextDependency, dependency, dependenciesToRemove);
|
||||||
@@ -390,4 +390,43 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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>
|
||||||
|
*/
|
||||||
|
protected boolean firstPathIsShortest(String left, String right) {
|
||||||
|
final String leftPath = left.replace('\\', '/');
|
||||||
|
final String rightPath = right.replace('\\', '/');
|
||||||
|
|
||||||
|
final int leftCount = countChar(leftPath, '/');
|
||||||
|
final int rightCount = countChar(rightPath, '/');
|
||||||
|
if (leftCount == rightCount) {
|
||||||
|
return leftPath.compareTo(rightPath) <= 0;
|
||||||
|
} else {
|
||||||
|
return leftCount < rightCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Counts the number of times the character is present in the string.
|
||||||
|
*
|
||||||
|
* @param string the string to count the characters in
|
||||||
|
* @param c the character to count
|
||||||
|
* @return the number of times the character is present in the string
|
||||||
|
*/
|
||||||
|
private int countChar(String string, char c) {
|
||||||
|
int count = 0;
|
||||||
|
final int max = string.length();
|
||||||
|
for (int i = 0; i < max; i++) {
|
||||||
|
if (c == string.charAt(i)) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,12 +93,17 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
addFalseNegativeCPEs(dependency);
|
addFalseNegativeCPEs(dependency);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes inaccurate matches on springframework CPEs.
|
||||||
|
*
|
||||||
|
* @param dependency the dependency to test for and remove known inaccurate CPE matches
|
||||||
|
*/
|
||||||
private void removeBadSpringMatches(Dependency dependency) {
|
private void removeBadSpringMatches(Dependency dependency) {
|
||||||
String mustContain = null;
|
String mustContain = null;
|
||||||
for (Identifier i : dependency.getIdentifiers()) {
|
for (Identifier i : dependency.getIdentifiers()) {
|
||||||
if ("maven".contains(i.getType())) {
|
if ("maven".contains(i.getType())) {
|
||||||
if (i.getValue() != null && i.getValue().startsWith("org.springframework.")) {
|
if (i.getValue() != null && i.getValue().startsWith("org.springframework.")) {
|
||||||
int endPoint = i.getValue().indexOf(":", 19);
|
final int endPoint = i.getValue().indexOf(":", 19);
|
||||||
if (endPoint >= 0) {
|
if (endPoint >= 0) {
|
||||||
mustContain = i.getValue().substring(19, endPoint).toLowerCase();
|
mustContain = i.getValue().substring(19, endPoint).toLowerCase();
|
||||||
break;
|
break;
|
||||||
@@ -107,9 +112,9 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mustContain != null) {
|
if (mustContain != null) {
|
||||||
Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
|
final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
|
||||||
while (itr.hasNext()) {
|
while (itr.hasNext()) {
|
||||||
Identifier i = itr.next();
|
final Identifier i = itr.next();
|
||||||
if ("cpe".contains(i.getType())
|
if ("cpe".contains(i.getType())
|
||||||
&& i.getValue() != null
|
&& i.getValue() != null
|
||||||
&& i.getValue().startsWith("cpe:/a:springsource:")
|
&& i.getValue().startsWith("cpe:/a:springsource:")
|
||||||
@@ -117,7 +122,6 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
itr.remove();
|
itr.remove();
|
||||||
//dependency.getIdentifiers().remove(i);
|
//dependency.getIdentifiers().remove(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
|
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
|
|
||||||
//strip any path information that may get added by ArchiveAnalyzer, etc.
|
//strip any path information that may get added by ArchiveAnalyzer, etc.
|
||||||
final File f = new File(dependency.getFileName());
|
final File f = dependency.getActualFile();
|
||||||
String fileName = f.getName();
|
String fileName = f.getName();
|
||||||
|
|
||||||
//remove file extension
|
//remove file extension
|
||||||
|
|||||||
@@ -293,13 +293,27 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
LOGGER.log(Level.FINE, msg, ex);
|
LOGGER.log(Level.FINE, msg, ex);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
File externalPom = null;
|
||||||
if (pomEntries.isEmpty()) {
|
if (pomEntries.isEmpty()) {
|
||||||
|
if (dependency.getActualFilePath().matches(".*\\.m2.repository\\b.*")) {
|
||||||
|
String pomPath = dependency.getActualFilePath();
|
||||||
|
pomPath = pomPath.substring(0, pomPath.lastIndexOf('.')) + ".pom";
|
||||||
|
externalPom = new File(pomPath);
|
||||||
|
if (externalPom.isFile()) {
|
||||||
|
pomEntries.add(pomPath);
|
||||||
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
for (String path : pomEntries) {
|
for (String path : pomEntries) {
|
||||||
Properties pomProperties = null;
|
Properties pomProperties = null;
|
||||||
try {
|
try {
|
||||||
|
if (externalPom == null) {
|
||||||
pomProperties = retrievePomProperties(path, jar);
|
pomProperties = retrievePomProperties(path, jar);
|
||||||
|
}
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LOGGER.log(Level.FINEST, "ignore this, failed reading a non-existent pom.properties", ex);
|
LOGGER.log(Level.FINEST, "ignore this, failed reading a non-existent pom.properties", ex);
|
||||||
}
|
}
|
||||||
@@ -313,11 +327,11 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
final String displayPath = String.format("%s%s%s",
|
final String displayPath = String.format("%s%s%s",
|
||||||
dependency.getFilePath(),
|
dependency.getFilePath(),
|
||||||
File.separator,
|
File.separator,
|
||||||
path); //.replaceAll("[\\/]", File.separator));
|
path);
|
||||||
final String displayName = String.format("%s%s%s",
|
final String displayName = String.format("%s%s%s",
|
||||||
dependency.getFileName(),
|
dependency.getFileName(),
|
||||||
File.separator,
|
File.separator,
|
||||||
path); //.replaceAll("[\\/]", File.separator));
|
path);
|
||||||
|
|
||||||
newDependency.setFileName(displayName);
|
newDependency.setFileName(displayName);
|
||||||
newDependency.setFilePath(displayPath);
|
newDependency.setFilePath(displayPath);
|
||||||
@@ -325,7 +339,11 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
engine.getDependencies().add(newDependency);
|
engine.getDependencies().add(newDependency);
|
||||||
Collections.sort(engine.getDependencies());
|
Collections.sort(engine.getDependencies());
|
||||||
} else {
|
} else {
|
||||||
|
if (externalPom == null) {
|
||||||
pom = retrievePom(path, jar);
|
pom = retrievePom(path, jar);
|
||||||
|
} else {
|
||||||
|
pom = retrievePom(externalPom);
|
||||||
|
}
|
||||||
foundSomething |= setPomEvidence(dependency, pom, pomProperties, classes);
|
foundSomething |= setPomEvidence(dependency, pom, pomProperties, classes);
|
||||||
}
|
}
|
||||||
} catch (AnalysisException ex) {
|
} catch (AnalysisException ex) {
|
||||||
@@ -523,6 +541,41 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads in the specified POM and converts it to a Model.
|
||||||
|
*
|
||||||
|
* @param file the pom.xml file
|
||||||
|
* @return returns a
|
||||||
|
* @throws AnalysisException is thrown if there is an exception extracting or parsing the POM
|
||||||
|
* {@link org.owasp.dependencycheck.jaxb.pom.generated.Model} object
|
||||||
|
*/
|
||||||
|
private Model retrievePom(File file) throws AnalysisException {
|
||||||
|
Model model = null;
|
||||||
|
try {
|
||||||
|
final FileInputStream stream = new FileInputStream(file);
|
||||||
|
final InputStreamReader reader = new InputStreamReader(stream, "UTF-8");
|
||||||
|
final InputSource xml = new InputSource(reader);
|
||||||
|
final SAXSource source = new SAXSource(xml);
|
||||||
|
model = readPom(source);
|
||||||
|
} catch (SecurityException ex) {
|
||||||
|
final String msg = String.format("Unable to parse pom '%s'; invalid signature", file.getPath());
|
||||||
|
LOGGER.log(Level.WARNING, msg);
|
||||||
|
LOGGER.log(Level.FINE, null, ex);
|
||||||
|
throw new AnalysisException(ex);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
final String msg = String.format("Unable to parse pom '%s'(IO Exception)", file.getPath());
|
||||||
|
LOGGER.log(Level.WARNING, msg);
|
||||||
|
LOGGER.log(Level.FINE, "", ex);
|
||||||
|
throw new AnalysisException(ex);
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
final String msg = String.format("Unexpected error during parsing of the pom '%s'", file.getPath());
|
||||||
|
LOGGER.log(Level.WARNING, msg);
|
||||||
|
LOGGER.log(Level.FINE, "", ex);
|
||||||
|
throw new AnalysisException(ex);
|
||||||
|
}
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the specified POM from a jar file and converts it to a Model.
|
* Retrieves the specified POM from a jar file and converts it to a Model.
|
||||||
*
|
*
|
||||||
@@ -583,9 +636,6 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
final String originalGroupID = groupid;
|
final String originalGroupID = groupid;
|
||||||
|
|
||||||
if (groupid != null && !groupid.isEmpty()) {
|
if (groupid != null && !groupid.isEmpty()) {
|
||||||
if (groupid.startsWith("org.") || groupid.startsWith("com.")) {
|
|
||||||
groupid = groupid.substring(4);
|
|
||||||
}
|
|
||||||
foundSomething = true;
|
foundSomething = true;
|
||||||
dependency.getVendorEvidence().addEvidence("pom", "groupid", groupid, Confidence.HIGHEST);
|
dependency.getVendorEvidence().addEvidence("pom", "groupid", groupid, Confidence.HIGHEST);
|
||||||
dependency.getProductEvidence().addEvidence("pom", "groupid", groupid, Confidence.LOW);
|
dependency.getProductEvidence().addEvidence("pom", "groupid", groupid, Confidence.LOW);
|
||||||
|
|||||||
@@ -24,15 +24,18 @@ import java.net.URL;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.owasp.dependencycheck.Engine;
|
import org.owasp.dependencycheck.Engine;
|
||||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
import org.owasp.dependencycheck.data.nexus.MavenArtifact;
|
import org.owasp.dependencycheck.data.nexus.MavenArtifact;
|
||||||
import org.owasp.dependencycheck.data.nexus.NexusSearch;
|
import org.owasp.dependencycheck.data.nexus.NexusSearch;
|
||||||
import org.owasp.dependencycheck.dependency.Confidence;
|
import org.owasp.dependencycheck.dependency.Confidence;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
import org.owasp.dependencycheck.dependency.Identifier;
|
import org.owasp.dependencycheck.utils.InvalidSettingException;
|
||||||
import org.owasp.dependencycheck.utils.Settings;
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Analyzer which will attempt to locate a dependency on a Nexus service by SHA-1 digest of the dependency.
|
* Analyzer which will attempt to locate a dependency on a Nexus service by SHA-1 digest of the dependency.
|
||||||
*
|
*
|
||||||
@@ -48,6 +51,10 @@ import org.owasp.dependencycheck.utils.Settings;
|
|||||||
* @author colezlaw
|
* @author colezlaw
|
||||||
*/
|
*/
|
||||||
public class NexusAnalyzer extends AbstractFileTypeAnalyzer {
|
public class NexusAnalyzer extends AbstractFileTypeAnalyzer {
|
||||||
|
/**
|
||||||
|
* The default URL - this will be used by the CentralAnalyzer to determine whether to enable this.
|
||||||
|
*/
|
||||||
|
public static final String DEFAULT_URL = "https://repository.sonatype.org/service/local/";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The logger.
|
* The logger.
|
||||||
@@ -74,6 +81,33 @@ public class NexusAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
*/
|
*/
|
||||||
private NexusSearch searcher;
|
private NexusSearch searcher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether to enable this analyzer or not.
|
||||||
|
*
|
||||||
|
* @return whether the analyzer should be enabled
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
/* Enable this analyzer ONLY if the Nexus URL has been set to something
|
||||||
|
other than the default one (if it's the default one, we'll use the
|
||||||
|
central one) and it's enabled by the user.
|
||||||
|
*/
|
||||||
|
boolean retval = false;
|
||||||
|
try {
|
||||||
|
if ((! DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL)))
|
||||||
|
&& Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED)) {
|
||||||
|
LOGGER.info("Enabling Nexus analyzer");
|
||||||
|
retval = true;
|
||||||
|
} else {
|
||||||
|
LOGGER.info("Nexus analyzer disabled");
|
||||||
|
}
|
||||||
|
} catch (InvalidSettingException ise) {
|
||||||
|
LOGGER.warning("Invalid setting. Disabling Nexus analyzer");
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the analyzer once before any analysis is performed.
|
* Initializes the analyzer once before any analysis is performed.
|
||||||
*
|
*
|
||||||
@@ -150,31 +184,12 @@ public class NexusAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
|
public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
|
if (! isEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
final MavenArtifact ma = searcher.searchSha1(dependency.getSha1sum());
|
final MavenArtifact ma = searcher.searchSha1(dependency.getSha1sum());
|
||||||
if (ma.getGroupId() != null && !"".equals(ma.getGroupId())) {
|
dependency.addAsEvidence("nexus", ma, Confidence.HIGH);
|
||||||
dependency.getVendorEvidence().addEvidence("nexus", "groupid", ma.getGroupId(), Confidence.HIGH);
|
|
||||||
}
|
|
||||||
if (ma.getArtifactId() != null && !"".equals(ma.getArtifactId())) {
|
|
||||||
dependency.getProductEvidence().addEvidence("nexus", "artifactid", ma.getArtifactId(), Confidence.HIGH);
|
|
||||||
}
|
|
||||||
if (ma.getVersion() != null && !"".equals(ma.getVersion())) {
|
|
||||||
dependency.getVersionEvidence().addEvidence("nexus", "version", ma.getVersion(), Confidence.HIGH);
|
|
||||||
}
|
|
||||||
if (ma.getArtifactUrl() != null && !"".equals(ma.getArtifactUrl())) {
|
|
||||||
boolean found = false;
|
|
||||||
for (Identifier i : dependency.getIdentifiers()) {
|
|
||||||
if ("maven".equals(i.getType()) && i.getValue().equals(ma.toString())) {
|
|
||||||
found = true;
|
|
||||||
i.setConfidence(Confidence.HIGHEST);
|
|
||||||
i.setUrl(ma.getArtifactUrl());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
dependency.addIdentifier("maven", ma.toString(), ma.getArtifactUrl(), Confidence.HIGHEST);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IllegalArgumentException iae) {
|
} catch (IllegalArgumentException iae) {
|
||||||
//dependency.addAnalysisException(new AnalysisException("Invalid SHA-1"));
|
//dependency.addAnalysisException(new AnalysisException("Invalid SHA-1"));
|
||||||
LOGGER.info(String.format("invalid sha-1 hash on %s", dependency.getFileName()));
|
LOGGER.info(String.format("invalid sha-1 hash on %s", dependency.getFileName()));
|
||||||
|
|||||||
@@ -0,0 +1,141 @@
|
|||||||
|
package org.owasp.dependencycheck.data.central;
|
||||||
|
|
||||||
|
import org.owasp.dependencycheck.data.nexus.MavenArtifact;
|
||||||
|
import org.owasp.dependencycheck.utils.InvalidSettingException;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
import org.owasp.dependencycheck.utils.URLConnectionFactory;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.xpath.XPath;
|
||||||
|
import javax.xml.xpath.XPathConstants;
|
||||||
|
import javax.xml.xpath.XPathFactory;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class of methods to search Maven Central via Central.
|
||||||
|
*
|
||||||
|
* @author colezlaw
|
||||||
|
*/
|
||||||
|
public class CentralSearch {
|
||||||
|
/**
|
||||||
|
* The URL for the Central service
|
||||||
|
*/
|
||||||
|
private final URL rootURL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to use the Proxy when making requests
|
||||||
|
*/
|
||||||
|
private boolean useProxy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for logging.
|
||||||
|
*/
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(CentralSearch.class.getName());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether we'll continue using the analyzer. If there's some sort
|
||||||
|
* of HTTP failure, we'll disable the analyzer.
|
||||||
|
*/
|
||||||
|
private boolean isEnabled = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a NexusSearch for the given repository URL.
|
||||||
|
*
|
||||||
|
* @param rootURL the URL of the repository on which searches should execute.
|
||||||
|
* Only parameters are added to this (so it should end in /select)
|
||||||
|
*/
|
||||||
|
public CentralSearch(URL rootURL) {
|
||||||
|
this.rootURL = rootURL;
|
||||||
|
if (null != Settings.getString(Settings.KEYS.PROXY_SERVER)) {
|
||||||
|
useProxy = true;
|
||||||
|
LOGGER.fine("Using proxy");
|
||||||
|
} else {
|
||||||
|
useProxy = false;
|
||||||
|
LOGGER.fine("Not using proxy");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches the configured Central URL for the given sha1 hash. If the artifact is found, a
|
||||||
|
* <code>MavenArtifact</code> is populated with the GAV.
|
||||||
|
*
|
||||||
|
* @param sha1 the SHA-1 hash string for which to search
|
||||||
|
* @return the populated Maven GAV.
|
||||||
|
* @throws IOException if it's unable to connect to the specified repository or if
|
||||||
|
* the specified artifact is not found.
|
||||||
|
*/
|
||||||
|
public List<MavenArtifact> searchSha1(String sha1) throws IOException {
|
||||||
|
if (null == sha1 || !sha1.matches("^[0-9A-Fa-f]{40}$")) {
|
||||||
|
throw new IllegalArgumentException("Invalid SHA1 format");
|
||||||
|
}
|
||||||
|
|
||||||
|
final URL url = new URL(rootURL + String.format("?q=1:\"%s\"&wt=xml", sha1));
|
||||||
|
|
||||||
|
LOGGER.info(String.format("Searching Central url %s", url.toString()));
|
||||||
|
|
||||||
|
// Determine if we need to use a proxy. The rules:
|
||||||
|
// 1) If the proxy is set, AND the setting is set to true, use the proxy
|
||||||
|
// 2) Otherwise, don't use the proxy (either the proxy isn't configured,
|
||||||
|
// or proxy is specifically set to false)
|
||||||
|
final HttpURLConnection conn = URLConnectionFactory.createHttpURLConnection(url, useProxy);
|
||||||
|
|
||||||
|
conn.setDoOutput(true);
|
||||||
|
|
||||||
|
// JSON would be more elegant, but there's not currently a dependency
|
||||||
|
// on JSON, so don't want to add one just for this
|
||||||
|
conn.addRequestProperty("Accept", "application/xml");
|
||||||
|
conn.connect();
|
||||||
|
|
||||||
|
if (conn.getResponseCode() == 200) {
|
||||||
|
boolean missing = false;
|
||||||
|
try {
|
||||||
|
final DocumentBuilder builder = DocumentBuilderFactory
|
||||||
|
.newInstance().newDocumentBuilder();
|
||||||
|
final Document doc = builder.parse(conn.getInputStream());
|
||||||
|
final XPath xpath = XPathFactory.newInstance().newXPath();
|
||||||
|
final String numFound = xpath.evaluate("/response/result/@numFound", doc);
|
||||||
|
if ("0".equals(numFound)) {
|
||||||
|
missing = true;
|
||||||
|
} else {
|
||||||
|
ArrayList<MavenArtifact> result = new ArrayList<MavenArtifact>();
|
||||||
|
NodeList docs = (NodeList)xpath.evaluate("/response/result/doc", doc, XPathConstants.NODESET);
|
||||||
|
for (int i = 0; i < docs.getLength(); i++) {
|
||||||
|
final String g = xpath.evaluate("./str[@name='g']", docs.item(i));
|
||||||
|
LOGGER.finest(String.format("GroupId: %s", g));
|
||||||
|
final String a = xpath.evaluate("./str[@name='a']", docs.item(i));
|
||||||
|
LOGGER.finest(String.format("ArtifactId: %s", a));
|
||||||
|
final String v = xpath.evaluate("./str[@name='v']", docs.item(i));
|
||||||
|
LOGGER.finest(String.format("Version: %s", v));
|
||||||
|
result.add(new MavenArtifact(g, a, v, url.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
// Anything else is jacked up XML stuff that we really can't recover
|
||||||
|
// from well
|
||||||
|
throw new IOException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (missing) {
|
||||||
|
throw new FileNotFoundException("Artifact not found in Central");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
final String msg = String.format("Could not connect to Central received response code: %d %s",
|
||||||
|
conn.getResponseCode(), conn.getResponseMessage());
|
||||||
|
LOGGER.fine(msg);
|
||||||
|
throw new IOException(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,10 +29,12 @@ import java.util.logging.Logger;
|
|||||||
* @author Jeremy Long <jeremy.long@owasp.org>
|
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||||
*/
|
*/
|
||||||
public final class CweDB {
|
public final class CweDB {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Logger.
|
* The Logger.
|
||||||
*/
|
*/
|
||||||
private static final Logger LOGGER = Logger.getLogger(CweDB.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(CweDB.class.getName());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Empty private constructor as this is a utility class.
|
* Empty private constructor as this is a utility class.
|
||||||
*/
|
*/
|
||||||
@@ -55,7 +57,9 @@ public final class CweDB {
|
|||||||
final String filePath = "data/cwe.hashmap.serialized";
|
final String filePath = "data/cwe.hashmap.serialized";
|
||||||
final InputStream input = CweDB.class.getClassLoader().getResourceAsStream(filePath);
|
final InputStream input = CweDB.class.getClassLoader().getResourceAsStream(filePath);
|
||||||
oin = new ObjectInputStream(input);
|
oin = new ObjectInputStream(input);
|
||||||
return (HashMap<String, String>) oin.readObject();
|
@SuppressWarnings("unchecked")
|
||||||
|
final HashMap<String, String> ret = (HashMap<String, String>) oin.readObject();
|
||||||
|
return ret;
|
||||||
} catch (ClassNotFoundException ex) {
|
} catch (ClassNotFoundException ex) {
|
||||||
LOGGER.log(Level.WARNING, "Unable to load CWE data. This should not be an issue.");
|
LOGGER.log(Level.WARNING, "Unable to load CWE data. This should not be an issue.");
|
||||||
LOGGER.log(Level.FINE, null, ex);
|
LOGGER.log(Level.FINE, null, ex);
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import java.util.SortedSet;
|
|||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
import org.owasp.dependencycheck.data.nexus.MavenArtifact;
|
||||||
import org.owasp.dependencycheck.utils.Checksum;
|
import org.owasp.dependencycheck.utils.Checksum;
|
||||||
import org.owasp.dependencycheck.utils.FileUtils;
|
import org.owasp.dependencycheck.utils.FileUtils;
|
||||||
|
|
||||||
@@ -316,6 +317,41 @@ public class Dependency implements Serializable, Comparable<Dependency> {
|
|||||||
this.identifiers.add(i);
|
this.identifiers.add(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the maven artifact as evidence.
|
||||||
|
*
|
||||||
|
* @param source The source of the evidence
|
||||||
|
* @param mavenArtifact The maven artifact
|
||||||
|
* @param confidence The confidence level of this evidence
|
||||||
|
*/
|
||||||
|
public void addAsEvidence(String source, MavenArtifact mavenArtifact, Confidence confidence) {
|
||||||
|
if (mavenArtifact.getGroupId() != null && !mavenArtifact.getGroupId().isEmpty()) {
|
||||||
|
this.getVendorEvidence().addEvidence(source, "groupid", mavenArtifact.getGroupId(), confidence);
|
||||||
|
}
|
||||||
|
if (mavenArtifact.getArtifactId() != null && !mavenArtifact.getArtifactId().isEmpty()) {
|
||||||
|
this.getProductEvidence().addEvidence(source, "artifactid", mavenArtifact.getArtifactId(), confidence);
|
||||||
|
}
|
||||||
|
if (mavenArtifact.getVersion() != null && !mavenArtifact.getVersion().isEmpty()) {
|
||||||
|
this.getVersionEvidence().addEvidence(source, "version", mavenArtifact.getVersion(), confidence);
|
||||||
|
}
|
||||||
|
if (mavenArtifact.getArtifactUrl() != null && !mavenArtifact.getArtifactUrl().isEmpty()) {
|
||||||
|
boolean found = false;
|
||||||
|
for (Identifier i : this.getIdentifiers()) {
|
||||||
|
if ("maven".equals(i.getType()) && i.getValue().equals(mavenArtifact.toString())) {
|
||||||
|
found = true;
|
||||||
|
i.setConfidence(Confidence.HIGHEST);
|
||||||
|
i.setUrl(mavenArtifact.getArtifactUrl());
|
||||||
|
LOGGER.fine(String.format("Already found identifier %s. Confidence set to highest", i.getValue()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
LOGGER.fine(String.format("Adding new maven identifier %s", mavenArtifact.toString()));
|
||||||
|
this.addIdentifier("maven", mavenArtifact.toString(), mavenArtifact.getArtifactUrl(), Confidence.HIGHEST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
*
|
*
|
||||||
@@ -324,6 +360,7 @@ public class Dependency implements Serializable, Comparable<Dependency> {
|
|||||||
public void addIdentifier(Identifier identifier) {
|
public void addIdentifier(Identifier identifier) {
|
||||||
this.identifiers.add(identifier);
|
this.identifiers.add(identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A set of identifiers that have been suppressed.
|
* A set of identifiers that have been suppressed.
|
||||||
*/
|
*/
|
||||||
@@ -441,6 +478,7 @@ public class Dependency implements Serializable, Comparable<Dependency> {
|
|||||||
public EvidenceCollection getVersionEvidence() {
|
public EvidenceCollection getVersionEvidence() {
|
||||||
return this.versionEvidence;
|
return this.versionEvidence;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The description of the JAR file.
|
* The description of the JAR file.
|
||||||
*/
|
*/
|
||||||
@@ -463,6 +501,7 @@ public class Dependency implements Serializable, Comparable<Dependency> {
|
|||||||
public void setDescription(String description) {
|
public void setDescription(String description) {
|
||||||
this.description = description;
|
this.description = description;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The license that this dependency uses.
|
* The license that this dependency uses.
|
||||||
*/
|
*/
|
||||||
@@ -485,6 +524,7 @@ public class Dependency implements Serializable, Comparable<Dependency> {
|
|||||||
public void setLicense(String license) {
|
public void setLicense(String license) {
|
||||||
this.license = license;
|
this.license = license;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of vulnerabilities for this dependency.
|
* A list of vulnerabilities for this dependency.
|
||||||
*/
|
*/
|
||||||
@@ -540,6 +580,7 @@ public class Dependency implements Serializable, Comparable<Dependency> {
|
|||||||
public void addVulnerability(Vulnerability vulnerability) {
|
public void addVulnerability(Vulnerability vulnerability) {
|
||||||
this.vulnerabilities.add(vulnerability);
|
this.vulnerabilities.add(vulnerability);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A collection of related dependencies.
|
* A collection of related dependencies.
|
||||||
*/
|
*/
|
||||||
@@ -579,7 +620,7 @@ public class Dependency implements Serializable, Comparable<Dependency> {
|
|||||||
* @return an integer representing the natural ordering
|
* @return an integer representing the natural ordering
|
||||||
*/
|
*/
|
||||||
public int compareTo(Dependency o) {
|
public int compareTo(Dependency o) {
|
||||||
return this.getFileName().compareToIgnoreCase(o.getFileName());
|
return this.getFilePath().compareToIgnoreCase(o.getFilePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -167,16 +167,29 @@ public class ReportGenerator {
|
|||||||
*/
|
*/
|
||||||
public void generateReports(String outputDir, String outputFormat) throws IOException, Exception {
|
public void generateReports(String outputDir, String outputFormat) throws IOException, Exception {
|
||||||
final String format = outputFormat.toUpperCase();
|
final String format = outputFormat.toUpperCase();
|
||||||
|
final String pathToCheck = outputDir.toLowerCase();
|
||||||
if (format.matches("^(XML|HTML|VULN|ALL)$")) {
|
if (format.matches("^(XML|HTML|VULN|ALL)$")) {
|
||||||
if ("XML".equalsIgnoreCase(format)) {
|
if ("XML".equalsIgnoreCase(format)) {
|
||||||
|
if (pathToCheck.endsWith(".xml")) {
|
||||||
|
generateReport("XmlReport", outputDir);
|
||||||
|
} else {
|
||||||
generateReports(outputDir, Format.XML);
|
generateReports(outputDir, Format.XML);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if ("HTML".equalsIgnoreCase(format)) {
|
if ("HTML".equalsIgnoreCase(format)) {
|
||||||
|
if (pathToCheck.endsWith(".html") || pathToCheck.endsWith(".htm")) {
|
||||||
|
generateReport("HtmlReport", outputDir);
|
||||||
|
} else {
|
||||||
generateReports(outputDir, Format.HTML);
|
generateReports(outputDir, Format.HTML);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if ("VULN".equalsIgnoreCase(format)) {
|
if ("VULN".equalsIgnoreCase(format)) {
|
||||||
|
if (pathToCheck.endsWith(".html") || pathToCheck.endsWith(".htm")) {
|
||||||
|
generateReport("VulnReport", outputDir);
|
||||||
|
} else {
|
||||||
generateReports(outputDir, Format.VULN);
|
generateReports(outputDir, Format.VULN);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if ("ALL".equalsIgnoreCase(format)) {
|
if ("ALL".equalsIgnoreCase(format)) {
|
||||||
generateReports(outputDir, Format.ALL);
|
generateReports(outputDir, Format.ALL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,11 +26,6 @@ import java.io.IOException;
|
|||||||
*/
|
*/
|
||||||
public class SuppressionParseException extends IOException {
|
public class SuppressionParseException extends IOException {
|
||||||
|
|
||||||
/**
|
|
||||||
* The serial version UID.
|
|
||||||
*/
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new SuppressionParseException.
|
* Creates a new SuppressionParseException.
|
||||||
*/
|
*/
|
||||||
@@ -50,7 +45,7 @@ public class SuppressionParseException extends IOException {
|
|||||||
/**
|
/**
|
||||||
* Creates a new SuppressionParseException.
|
* Creates a new SuppressionParseException.
|
||||||
*
|
*
|
||||||
* @param ex the cause of the download failure.
|
* @param ex the cause of the parse exception
|
||||||
*/
|
*/
|
||||||
public SuppressionParseException(Throwable ex) {
|
public SuppressionParseException(Throwable ex) {
|
||||||
super(ex);
|
super(ex);
|
||||||
@@ -60,7 +55,7 @@ public class SuppressionParseException extends IOException {
|
|||||||
* Creates a new SuppressionParseException.
|
* Creates a new SuppressionParseException.
|
||||||
*
|
*
|
||||||
* @param msg a message for the exception.
|
* @param msg a message for the exception.
|
||||||
* @param ex the cause of the download failure.
|
* @param ex the cause of the parse exception
|
||||||
*/
|
*/
|
||||||
public SuppressionParseException(String msg, Throwable ex) {
|
public SuppressionParseException(String msg, Throwable ex) {
|
||||||
super(msg, ex);
|
super(msg, ex);
|
||||||
|
|||||||
@@ -266,10 +266,14 @@ public class SuppressionRule {
|
|||||||
return gav != null;
|
return gav != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A flag indicating whether or not the suppression rule is a core/base rule that should not be included in the
|
||||||
|
* resulting report in the "suppressed" section.
|
||||||
|
*/
|
||||||
private boolean base;
|
private boolean base;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value of base
|
* Get the value of base.
|
||||||
*
|
*
|
||||||
* @return the value of base
|
* @return the value of base
|
||||||
*/
|
*/
|
||||||
@@ -278,7 +282,7 @@ public class SuppressionRule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the value of base
|
* Set the value of base.
|
||||||
*
|
*
|
||||||
* @param base new value of base
|
* @param base new value of base
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -54,7 +54,9 @@ public final class DBUtils {
|
|||||||
int id = 0;
|
int id = 0;
|
||||||
try {
|
try {
|
||||||
rs = statement.getGeneratedKeys();
|
rs = statement.getGeneratedKeys();
|
||||||
rs.next();
|
if (!rs.next()) {
|
||||||
|
throw new DatabaseException("Unable to get primary key for inserted row");
|
||||||
|
}
|
||||||
id = rs.getInt(1);
|
id = rs.getInt(1);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
throw new DatabaseException("Unable to get primary key for inserted row");
|
throw new DatabaseException("Unable to get primary key for inserted row");
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ public class DependencyVersion implements Iterable, Comparable<DependencyVersion
|
|||||||
public final void parseVersion(String version) {
|
public final void parseVersion(String version) {
|
||||||
versionParts = new ArrayList<String>();
|
versionParts = new ArrayList<String>();
|
||||||
if (version != null) {
|
if (version != null) {
|
||||||
final Pattern rx = Pattern.compile("(\\d+|[a-z]+\\d+|(release|beta|alpha)$)");
|
final Pattern rx = Pattern.compile("(\\d+[a-z]{1,3}$|[a-z]+\\d+|\\d+|(release|beta|alpha)$)");
|
||||||
final Matcher matcher = rx.matcher(version.toLowerCase());
|
final Matcher matcher = rx.matcher(version.toLowerCase());
|
||||||
while (matcher.find()) {
|
while (matcher.find()) {
|
||||||
versionParts.add(matcher.group());
|
versionParts.add(matcher.group());
|
||||||
@@ -198,8 +198,8 @@ public class DependencyVersion implements Iterable, Comparable<DependencyVersion
|
|||||||
|
|
||||||
boolean ret = true;
|
boolean ret = true;
|
||||||
for (int i = 0; i < max; i++) {
|
for (int i = 0; i < max; i++) {
|
||||||
String thisVersion = this.versionParts.get(i);
|
final String thisVersion = this.versionParts.get(i);
|
||||||
String otherVersion = version.getVersionParts().get(i);
|
final String otherVersion = version.getVersionParts().get(i);
|
||||||
if (i >= 3) {
|
if (i >= 3) {
|
||||||
if (thisVersion.compareToIgnoreCase(otherVersion) >= 0) {
|
if (thisVersion.compareToIgnoreCase(otherVersion) >= 0) {
|
||||||
ret = false;
|
ret = false;
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public final class DependencyVersionUtil {
|
|||||||
/**
|
/**
|
||||||
* Regular expression to extract version numbers from file names.
|
* Regular expression to extract version numbers from file names.
|
||||||
*/
|
*/
|
||||||
private static final Pattern RX_VERSION = Pattern.compile("\\d+(\\.\\d{1,6})+(\\.?([_-](release|beta|alpha)|[a-zA-Z_-]{1,3}\\d{1,8}))?");
|
private static final Pattern RX_VERSION = Pattern.compile("\\d+(\\.\\d{1,6})+(\\.?([_-](release|beta|alpha|\\d+)|[a-zA-Z_-]{1,3}\\d{0,8}))?");
|
||||||
/**
|
/**
|
||||||
* Regular expression to extract a single version number without periods. This is a last ditch effort just to check
|
* Regular expression to extract a single version number without periods. This is a last ditch effort just to check
|
||||||
* in case we are missing a version number using the previous regex.
|
* in case we are missing a version number using the previous regex.
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ org.owasp.dependencycheck.analyzer.CpeSuppressionAnalyzer
|
|||||||
org.owasp.dependencycheck.analyzer.DependencyBundlingAnalyzer
|
org.owasp.dependencycheck.analyzer.DependencyBundlingAnalyzer
|
||||||
org.owasp.dependencycheck.analyzer.NvdCveAnalyzer
|
org.owasp.dependencycheck.analyzer.NvdCveAnalyzer
|
||||||
org.owasp.dependencycheck.analyzer.VulnerabilitySuppressionAnalyzer
|
org.owasp.dependencycheck.analyzer.VulnerabilitySuppressionAnalyzer
|
||||||
|
org.owasp.dependencycheck.analyzer.CentralAnalyzer
|
||||||
org.owasp.dependencycheck.analyzer.NexusAnalyzer
|
org.owasp.dependencycheck.analyzer.NexusAnalyzer
|
||||||
org.owasp.dependencycheck.analyzer.NuspecAnalyzer
|
org.owasp.dependencycheck.analyzer.NuspecAnalyzer
|
||||||
org.owasp.dependencycheck.analyzer.AssemblyAnalyzer
|
org.owasp.dependencycheck.analyzer.AssemblyAnalyzer
|
||||||
@@ -9,6 +9,15 @@
|
|||||||
<cpe>cpe:/a:springsource:spring_framework</cpe>
|
<cpe>cpe:/a:springsource:spring_framework</cpe>
|
||||||
<cpe>cpe:/a:vmware:springsource_spring_framework</cpe>
|
<cpe>cpe:/a:vmware:springsource_spring_framework</cpe>
|
||||||
</suppress>
|
</suppress>
|
||||||
|
<suppress base="true">
|
||||||
|
<notes><![CDATA[
|
||||||
|
This suppresses false positives identified on spring security.
|
||||||
|
]]></notes>
|
||||||
|
<filePath regex="true">.*spring-security-[^\\/]*\.jar$</filePath>
|
||||||
|
<cpe>cpe:/a:mod_security:mod_security</cpe>
|
||||||
|
<cpe>cpe:/a:springsource:spring_framework</cpe>
|
||||||
|
<cpe>cpe:/a:vmware:springsource_spring_framework</cpe>
|
||||||
|
</suppress>
|
||||||
<suppress base="true">
|
<suppress base="true">
|
||||||
<notes><![CDATA[
|
<notes><![CDATA[
|
||||||
This suppreses additional false positives for the xstream library that occur because spring has a copy of this library.
|
This suppreses additional false positives for the xstream library that occur because spring has a copy of this library.
|
||||||
@@ -35,7 +44,22 @@
|
|||||||
<notes><![CDATA[
|
<notes><![CDATA[
|
||||||
Suppresses false positives on Jersey core client.
|
Suppresses false positives on Jersey core client.
|
||||||
]]></notes>
|
]]></notes>
|
||||||
<gav regex="true">org\.glassfish\.jersey\.core:jersey-(client|common):.*</gav>
|
<gav regex="true">(com\.sun\.jersey|org\.glassfish\.jersey\.core):jersey-(client|common):.*</gav>
|
||||||
|
<cpe>cpe:/a:oracle:glassfish</cpe>
|
||||||
|
<cpe>cpe:/a:oracle:oracle_client</cpe>
|
||||||
|
</suppress>
|
||||||
|
<suppress>
|
||||||
|
<notes><![CDATA[
|
||||||
|
Suppresses false positives on the grizzly-framework
|
||||||
|
]]></notes>
|
||||||
|
<gav regex="true">org\.glassfish\.grizzly:grizzly-framework:.*</gav>
|
||||||
<cpe>cpe:/a:oracle:glassfish</cpe>
|
<cpe>cpe:/a:oracle:glassfish</cpe>
|
||||||
</suppress>
|
</suppress>
|
||||||
|
<suppress>
|
||||||
|
<notes><![CDATA[
|
||||||
|
Suppresses false positives on the grizzly-framework
|
||||||
|
]]></notes>
|
||||||
|
<gav regex="true">org\.forgerock\.opendj:opendj-ldap-sdk:.*</gav>
|
||||||
|
<cpe>cpe:/a:ldap_project:ldap</cpe>
|
||||||
|
</suppress>
|
||||||
</suppressions>
|
</suppressions>
|
||||||
@@ -58,3 +58,7 @@ analyzer.nexus.url=https://repository.sonatype.org/service/local/
|
|||||||
# If set to true, the proxy will still ONLY be used if the proxy properties (proxy.url, proxy.port)
|
# If set to true, the proxy will still ONLY be used if the proxy properties (proxy.url, proxy.port)
|
||||||
# are configured
|
# are configured
|
||||||
analyzer.nexus.proxy=true
|
analyzer.nexus.proxy=true
|
||||||
|
|
||||||
|
# the URL for searching search.maven.org for SHA-1 and whether it's enabled
|
||||||
|
analyzer.central.enabled=true
|
||||||
|
analyzer.central.url=http://search.maven.org/solrsearch/select
|
||||||
|
|||||||
@@ -906,6 +906,6 @@ arising out of or in connection with the use of this tool, the analysis performe
|
|||||||
## END SUPPRESSED VULNERABILITIES
|
## END SUPPRESSED VULNERABILITIES
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div><br/><br/>This report contains data retrieved from the <a href="nvd.nist.gov">National Vulnerability Database</a>.</div>
|
<div><br/><br/>This report contains data retrieved from the <a href="http://nvd.nist.gov">National Vulnerability Database</a>.</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -236,6 +236,6 @@ arising out of or in connection with the use of this tool, the analysis performe
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<p><br/><br/>This report contains data retrieved from the <a href="nvd.nist.gov">National Vulnerability Database</a>.</p>
|
<p><br/><br/>This report contains data retrieved from the <a href="http://nvd.nist.gov">National Vulnerability Database</a>.</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import org.junit.Before;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.owasp.dependencycheck.data.nvdcve.CveDB;
|
import org.owasp.dependencycheck.data.nvdcve.CveDB;
|
||||||
import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
|
import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
|
||||||
import org.owasp.dependencycheck.reporting.ReportGenerator;
|
import org.owasp.dependencycheck.reporting.ReportGenerator;
|
||||||
import org.owasp.dependencycheck.utils.Settings;
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
@@ -42,26 +41,6 @@ public class EngineIntegrationTest extends BaseTest {
|
|||||||
public void tearDown() {
|
public void tearDown() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test of scan method, of class Engine.
|
|
||||||
*
|
|
||||||
* @throws Exception is thrown when an exception occurs.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testScan() throws Exception {
|
|
||||||
String testClasses = "target/test-classes/*.zip";
|
|
||||||
boolean autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
|
|
||||||
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false);
|
|
||||||
Engine instance = new Engine();
|
|
||||||
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
|
|
||||||
instance.scan(testClasses);
|
|
||||||
assertTrue(instance.getDependencies().size() > 0);
|
|
||||||
for (Dependency d : instance.getDependencies()) {
|
|
||||||
assertTrue("non-zip file collected " + d.getFileName(), d.getFileName().toLowerCase().endsWith(".zip"));
|
|
||||||
}
|
|
||||||
instance.cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test running the entire engine.
|
* Test running the entire engine.
|
||||||
*
|
*
|
||||||
@@ -81,8 +60,7 @@ public class EngineIntegrationTest extends BaseTest {
|
|||||||
cveDB.open();
|
cveDB.open();
|
||||||
DatabaseProperties dbProp = cveDB.getDatabaseProperties();
|
DatabaseProperties dbProp = cveDB.getDatabaseProperties();
|
||||||
cveDB.close();
|
cveDB.close();
|
||||||
ReportGenerator rg = new ReportGenerator("DependencyCheck",
|
ReportGenerator rg = new ReportGenerator("DependencyCheck", instance.getDependencies(), instance.getAnalyzers(), dbProp);
|
||||||
instance.getDependencies(), instance.getAnalyzers(), dbProp);
|
|
||||||
rg.generateReports("./target/", "ALL");
|
rg.generateReports("./target/", "ALL");
|
||||||
instance.cleanup();
|
instance.cleanup();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,9 +25,11 @@ import java.util.Set;
|
|||||||
import org.apache.lucene.index.CorruptIndexException;
|
import org.apache.lucene.index.CorruptIndexException;
|
||||||
import org.apache.lucene.queryparser.classic.ParseException;
|
import org.apache.lucene.queryparser.classic.ParseException;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.owasp.dependencycheck.data.cpe.AbstractDatabaseTestCase;
|
import org.owasp.dependencycheck.data.cpe.AbstractDatabaseTestCase;
|
||||||
import org.owasp.dependencycheck.data.cpe.IndexEntry;
|
import org.owasp.dependencycheck.data.cpe.IndexEntry;
|
||||||
|
import org.owasp.dependencycheck.dependency.Confidence;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
import org.owasp.dependencycheck.dependency.Identifier;
|
import org.owasp.dependencycheck.dependency.Identifier;
|
||||||
|
|
||||||
@@ -183,6 +185,30 @@ public class CPEAnalyzerIntegrationTest extends AbstractDatabaseTestCase {
|
|||||||
//Assert.assertTrue("Incorrect match - spring", spring.getIdentifiers().get(0).getValue().equals(expResultSpring));
|
//Assert.assertTrue("Incorrect match - spring", spring.getIdentifiers().get(0).getValue().equals(expResultSpring));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test of determineIdentifiers method, of class CPEAnalyzer.
|
||||||
|
*
|
||||||
|
* @throws Exception is thrown when an exception occurs
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testDetermineIdentifiers() throws Exception {
|
||||||
|
Dependency openssl = new Dependency();
|
||||||
|
openssl.getVendorEvidence().addEvidence("test", "vendor", "openssl", Confidence.HIGHEST);
|
||||||
|
openssl.getProductEvidence().addEvidence("test", "product", "openssl", Confidence.HIGHEST);
|
||||||
|
openssl.getVersionEvidence().addEvidence("test", "version", "1.0.1c", Confidence.HIGHEST);
|
||||||
|
|
||||||
|
CPEAnalyzer instance = new CPEAnalyzer();
|
||||||
|
instance.open();
|
||||||
|
instance.determineIdentifiers(openssl, "openssl", "openssl", Confidence.HIGHEST);
|
||||||
|
instance.close();
|
||||||
|
|
||||||
|
String expResult = "cpe:/a:openssl:openssl:1.0.1c";
|
||||||
|
Identifier expIdentifier = new Identifier("cpe", expResult, expResult);
|
||||||
|
|
||||||
|
assertTrue(openssl.getIdentifiers().contains(expIdentifier));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test of searchCPE method, of class CPEAnalyzer.
|
* Test of searchCPE method, of class CPEAnalyzer.
|
||||||
*
|
*
|
||||||
@@ -193,12 +219,12 @@ public class CPEAnalyzerIntegrationTest extends AbstractDatabaseTestCase {
|
|||||||
String vendor = "apache software foundation";
|
String vendor = "apache software foundation";
|
||||||
String product = "struts 2 core";
|
String product = "struts 2 core";
|
||||||
String version = "2.1.2";
|
String version = "2.1.2";
|
||||||
String expResult = "cpe:/a:apache:struts:2.1.2";
|
String expVendor = "apache";
|
||||||
|
String expProduct = "struts";
|
||||||
|
|
||||||
CPEAnalyzer instance = new CPEAnalyzer();
|
CPEAnalyzer instance = new CPEAnalyzer();
|
||||||
instance.open();
|
instance.open();
|
||||||
|
|
||||||
//TODO - yeah, not a very good test as the results are the same with or without weighting...
|
|
||||||
Set<String> productWeightings = new HashSet<String>(1);
|
Set<String> productWeightings = new HashSet<String>(1);
|
||||||
productWeightings.add("struts2");
|
productWeightings.add("struts2");
|
||||||
|
|
||||||
@@ -206,9 +232,16 @@ public class CPEAnalyzerIntegrationTest extends AbstractDatabaseTestCase {
|
|||||||
vendorWeightings.add("apache");
|
vendorWeightings.add("apache");
|
||||||
|
|
||||||
List<IndexEntry> result = instance.searchCPE(vendor, product, productWeightings, vendorWeightings);
|
List<IndexEntry> result = instance.searchCPE(vendor, product, productWeightings, vendorWeightings);
|
||||||
//TODO fix this assert
|
|
||||||
//Assert.assertEquals(expResult, result.get(0).getName());
|
|
||||||
|
|
||||||
instance.close();
|
instance.close();
|
||||||
|
|
||||||
|
boolean found = false;
|
||||||
|
for (IndexEntry entry : result) {
|
||||||
|
if (expVendor.equals(entry.getVendor()) && expProduct.equals(entry.getProduct())) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertTrue("apache:struts was not identified", found);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,4 +86,40 @@ public class DependencyBundlingAnalyzerTest extends BaseTest {
|
|||||||
assertEquals(expResult, result);
|
assertEquals(expResult, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFirstPathIsShortest() {
|
||||||
|
DependencyBundlingAnalyzer instance = new DependencyBundlingAnalyzer();
|
||||||
|
|
||||||
|
String left = "./a/c.jar";
|
||||||
|
String right = "./d/e/f.jar";
|
||||||
|
boolean expResult = true;
|
||||||
|
boolean result = instance.firstPathIsShortest(left, right);
|
||||||
|
assertEquals(expResult, result);
|
||||||
|
|
||||||
|
left = "./a/b/c.jar";
|
||||||
|
right = "./d/e/f.jar";
|
||||||
|
expResult = true;
|
||||||
|
result = instance.firstPathIsShortest(left, right);
|
||||||
|
assertEquals(expResult, result);
|
||||||
|
|
||||||
|
left = "./d/b/c.jar";
|
||||||
|
right = "./a/e/f.jar";
|
||||||
|
expResult = false;
|
||||||
|
result = instance.firstPathIsShortest(left, right);
|
||||||
|
assertEquals(expResult, result);
|
||||||
|
|
||||||
|
left = "./a/b/c.jar";
|
||||||
|
right = "./d/f.jar";
|
||||||
|
expResult = false;
|
||||||
|
result = instance.firstPathIsShortest(left, right);
|
||||||
|
assertEquals(expResult, result);
|
||||||
|
|
||||||
|
left = "./a/b/c.jar";
|
||||||
|
right = "./a/b/c.jar";
|
||||||
|
expResult = true;
|
||||||
|
result = instance.firstPathIsShortest(left, right);
|
||||||
|
assertEquals(expResult, result);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package org.owasp.dependencycheck.data.central;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.owasp.dependencycheck.BaseTest;
|
||||||
|
import org.owasp.dependencycheck.data.nexus.MavenArtifact;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by colezlaw on 10/13/14.
|
||||||
|
*/
|
||||||
|
public class CentralSearchTest extends BaseTest {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(CentralSearchTest.class.getName());
|
||||||
|
private CentralSearch searcher;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
String centralUrl = Settings.getString(Settings.KEYS.ANALYZER_CENTRAL_URL);
|
||||||
|
LOGGER.fine(centralUrl);
|
||||||
|
searcher = new CentralSearch(new URL(centralUrl));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testNullSha1() throws Exception { searcher.searchSha1(null); }
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testMalformedSha1() throws Exception {
|
||||||
|
searcher.searchSha1("invalid");
|
||||||
|
}
|
||||||
|
|
||||||
|
// This test does generate network traffic and communicates with a host
|
||||||
|
// you may not be able to reach. Remove the @Ignore annotation if you want to
|
||||||
|
// test it anyway
|
||||||
|
@Test
|
||||||
|
public void testValidSha1() throws Exception {
|
||||||
|
List<MavenArtifact> ma = searcher.searchSha1("9977a8d04e75609cf01badc4eb6a9c7198c4c5ea");
|
||||||
|
assertEquals("Incorrect group", "org.apache.maven.plugins", ma.get(0).getGroupId());
|
||||||
|
assertEquals("Incorrect artifact", "maven-compiler-plugin", ma.get(0).getArtifactId());
|
||||||
|
assertEquals("Incorrect version", "3.1", ma.get(0).getVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
// This test does generate network traffic and communicates with a host
|
||||||
|
// you may not be able to reach. Remove the @Ignore annotation if you want to
|
||||||
|
// test it anyway
|
||||||
|
@Test(expected = FileNotFoundException.class)
|
||||||
|
public void testMissingSha1() throws Exception {
|
||||||
|
searcher.searchSha1("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
|
||||||
|
}
|
||||||
|
|
||||||
|
// This test should give us multiple results back from Central
|
||||||
|
@Test
|
||||||
|
public void testMultipleReturns() throws Exception {
|
||||||
|
List<MavenArtifact> ma = searcher.searchSha1("94A9CE681A42D0352B3AD22659F67835E560D107");
|
||||||
|
assertTrue(ma.size() > 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,10 +23,12 @@ import java.util.Set;
|
|||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.owasp.dependencycheck.data.nexus.MavenArtifact;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -294,4 +296,34 @@ public class DependencyTest {
|
|||||||
EvidenceCollection result = instance.getVersionEvidence();
|
EvidenceCollection result = instance.getVersionEvidence();
|
||||||
assertTrue(true); //this is just a getter setter pair.
|
assertTrue(true); //this is just a getter setter pair.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test of addAsEvidence method, of class Dependency.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testAddAsEvidence() {
|
||||||
|
Dependency instance = new Dependency();
|
||||||
|
MavenArtifact mavenArtifact = new MavenArtifact("group", "artifact", "version", "url");
|
||||||
|
instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH);
|
||||||
|
assertTrue(instance.getEvidence().contains(Confidence.HIGH));
|
||||||
|
assertFalse(instance.getEvidence().getEvidence("pom", "groupid").isEmpty());
|
||||||
|
assertFalse(instance.getEvidence().getEvidence("pom", "artifactid").isEmpty());
|
||||||
|
assertFalse(instance.getEvidence().getEvidence("pom", "version").isEmpty());
|
||||||
|
assertFalse(instance.getIdentifiers().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test of addAsEvidence method, of class Dependency.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testAddAsEvidenceWithEmptyArtefact() {
|
||||||
|
Dependency instance = new Dependency();
|
||||||
|
MavenArtifact mavenArtifact = new MavenArtifact(null, null, null, null);
|
||||||
|
instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH);
|
||||||
|
assertFalse(instance.getEvidence().contains(Confidence.HIGH));
|
||||||
|
assertTrue(instance.getEvidence().getEvidence("pom", "groupid").isEmpty());
|
||||||
|
assertTrue(instance.getEvidence().getEvidence("pom", "artifactid").isEmpty());
|
||||||
|
assertTrue(instance.getEvidence().getEvidence("pom", "version").isEmpty());
|
||||||
|
assertTrue(instance.getIdentifiers().isEmpty());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,13 +54,13 @@ public class DependencyVersionUtilTest {
|
|||||||
* Test of parseVersion method, of class DependencyVersionUtil.
|
* Test of parseVersion method, of class DependencyVersionUtil.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testParseVersionFromFileName() {
|
public void testParseVersion() {
|
||||||
final String[] fileName = {"something-0.9.5.jar", "lib2-1.1.jar", "lib1.5r4-someflag-R26.jar",
|
final String[] fileName = {"something-0.9.5.jar", "lib2-1.1.jar", "lib1.5r4-someflag-R26.jar",
|
||||||
"lib-1.2.5-dev-20050313.jar", "testlib_V4.4.0.jar", "lib-core-2.0.0-RC1-SNAPSHOT.jar",
|
"lib-1.2.5-dev-20050313.jar", "testlib_V4.4.0.jar", "lib-core-2.0.0-RC1-SNAPSHOT.jar",
|
||||||
"lib-jsp-2.0.1_R114940.jar", "dev-api-2.3.11_R121413.jar", "lib-api-3.7-SNAPSHOT.jar",
|
"lib-jsp-2.0.1_R114940.jar", "dev-api-2.3.11_R121413.jar", "lib-api-3.7-SNAPSHOT.jar",
|
||||||
"-", "", "1.3-beta", "6"};
|
"-", "", "1.3-beta", "6", "openssl1.0.1c", "jsf-impl-2.2.8-02.jar"};
|
||||||
final String[] expResult = {"0.9.5", "1.1", "1.5.r4", "1.2.5", "4.4.0", "2.0.0.rc1",
|
final String[] expResult = {"0.9.5", "1.1", "1.5.r4", "1.2.5", "4.4.0", "2.0.0.rc1",
|
||||||
"2.0.1.r114940", "2.3.11.r121413", "3.7", "-", null, "1.3.beta", "6"};
|
"2.0.1.r114940", "2.3.11.r121413", "3.7", "-", null, "1.3.beta", "6", "1.0.1c", "2.2.8.02"};
|
||||||
|
|
||||||
for (int i = 0; i < fileName.length; i++) {
|
for (int i = 0; i < fileName.length; i++) {
|
||||||
final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName[i]);
|
final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName[i]);
|
||||||
|
|||||||
@@ -59,3 +59,7 @@ analyzer.nexus.url=https://repository.sonatype.org/service/local/
|
|||||||
# If set to true, the proxy will still ONLY be used if the proxy properties (proxy.url, proxy.port)
|
# If set to true, the proxy will still ONLY be used if the proxy properties (proxy.url, proxy.port)
|
||||||
# are configured
|
# are configured
|
||||||
analyzer.nexus.proxy=true
|
analyzer.nexus.proxy=true
|
||||||
|
|
||||||
|
# the URL for searching search.maven.org for SHA-1 and whether it's enabled
|
||||||
|
analyzer.central.enabled=true
|
||||||
|
analyzer.central.url=http://search.maven.org/solrsearch/select
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp</groupId>
|
<groupId>org.owasp</groupId>
|
||||||
<artifactId>dependency-check-parent</artifactId>
|
<artifactId>dependency-check-parent</artifactId>
|
||||||
<version>1.2.5</version>
|
<version>1.2.6-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<groupId>org.owasp</groupId>
|
<groupId>org.owasp</groupId>
|
||||||
<artifactId>dependency-check-jenkins</artifactId>
|
<artifactId>dependency-check-jenkins</artifactId>
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp</groupId>
|
<groupId>org.owasp</groupId>
|
||||||
<artifactId>dependency-check-parent</artifactId>
|
<artifactId>dependency-check-parent</artifactId>
|
||||||
<version>1.2.5</version>
|
<version>1.2.6-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>dependency-check-maven</artifactId>
|
<artifactId>dependency-check-maven</artifactId>
|
||||||
|
|||||||
@@ -46,7 +46,9 @@ import org.apache.maven.settings.Proxy;
|
|||||||
import org.owasp.dependencycheck.Engine;
|
import org.owasp.dependencycheck.Engine;
|
||||||
import org.owasp.dependencycheck.analyzer.DependencyBundlingAnalyzer;
|
import org.owasp.dependencycheck.analyzer.DependencyBundlingAnalyzer;
|
||||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
|
import org.owasp.dependencycheck.data.nexus.MavenArtifact;
|
||||||
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
||||||
|
import org.owasp.dependencycheck.dependency.Confidence;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
import org.owasp.dependencycheck.dependency.Identifier;
|
import org.owasp.dependencycheck.dependency.Identifier;
|
||||||
import org.owasp.dependencycheck.dependency.Vulnerability;
|
import org.owasp.dependencycheck.dependency.Vulnerability;
|
||||||
@@ -58,9 +60,13 @@ import org.owasp.dependencycheck.utils.Settings;
|
|||||||
*
|
*
|
||||||
* @author Jeremy Long <jeremy.long@owasp.org>
|
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||||
*/
|
*/
|
||||||
@Mojo(name = "check", defaultPhase = LifecyclePhase.COMPILE, threadSafe = true,
|
@Mojo(
|
||||||
|
name = "check",
|
||||||
|
defaultPhase = LifecyclePhase.COMPILE,
|
||||||
|
threadSafe = true,
|
||||||
requiresDependencyResolution = ResolutionScope.RUNTIME_PLUS_SYSTEM,
|
requiresDependencyResolution = ResolutionScope.RUNTIME_PLUS_SYSTEM,
|
||||||
requiresOnline = true)
|
requiresOnline = true
|
||||||
|
)
|
||||||
public class DependencyCheckMojo extends ReportAggregationMojo {
|
public class DependencyCheckMojo extends ReportAggregationMojo {
|
||||||
|
|
||||||
//<editor-fold defaultstate="collapsed" desc="Private fields">
|
//<editor-fold defaultstate="collapsed" desc="Private fields">
|
||||||
@@ -292,6 +298,7 @@ public class DependencyCheckMojo extends ReportAggregationMojo {
|
|||||||
@Parameter(property = "externalReport")
|
@Parameter(property = "externalReport")
|
||||||
@Deprecated
|
@Deprecated
|
||||||
private String externalReport = null;
|
private String externalReport = null;
|
||||||
|
|
||||||
// </editor-fold>
|
// </editor-fold>
|
||||||
/**
|
/**
|
||||||
* Constructs a new dependency-check-mojo.
|
* Constructs a new dependency-check-mojo.
|
||||||
@@ -326,8 +333,20 @@ public class DependencyCheckMojo extends ReportAggregationMojo {
|
|||||||
if (excludeFromScan(a)) {
|
if (excludeFromScan(a)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
final List<Dependency> deps = localEngine.scan(a.getFile().getAbsoluteFile());
|
||||||
localEngine.scan(a.getFile().getAbsolutePath());
|
if (deps != null) {
|
||||||
|
if (deps.size() == 1) {
|
||||||
|
final Dependency d = deps.get(0);
|
||||||
|
if (d != null) {
|
||||||
|
final MavenArtifact ma = new MavenArtifact(a.getGroupId(), a.getArtifactId(), a.getVersion());
|
||||||
|
d.addAsEvidence("pom", ma, Confidence.HIGHEST);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
final String msg = String.format("More then 1 dependency was identified in first pass scan of '%s:%s:%s'",
|
||||||
|
a.getGroupId(), a.getArtifactId(), a.getVersion());
|
||||||
|
LOGGER.info(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
localEngine.analyzeDependencies();
|
localEngine.analyzeDependencies();
|
||||||
|
|
||||||
@@ -396,8 +415,7 @@ public class DependencyCheckMojo extends ReportAggregationMojo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (proxyUrl != null && !proxyUrl.isEmpty()) {
|
if (proxyUrl != null && !proxyUrl.isEmpty()) {
|
||||||
LOGGER.warning("Deprecated configuration detected, proxyUrl will be ignored; use the maven settings "
|
LOGGER.warning("Deprecated configuration detected, proxyUrl will be ignored; use the maven settings " + "to configure the proxy instead");
|
||||||
+ "to configure the proxy instead");
|
|
||||||
}
|
}
|
||||||
final Proxy proxy = getMavenProxy();
|
final Proxy proxy = getMavenProxy();
|
||||||
if (proxy != null) {
|
if (proxy != null) {
|
||||||
@@ -510,8 +528,8 @@ public class DependencyCheckMojo extends ReportAggregationMojo {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
//</editor-fold>
|
|
||||||
|
|
||||||
|
//</editor-fold>
|
||||||
/**
|
/**
|
||||||
* Executes the dependency-check and generates the report.
|
* Executes the dependency-check and generates the report.
|
||||||
*
|
*
|
||||||
@@ -530,8 +548,7 @@ public class DependencyCheckMojo extends ReportAggregationMojo {
|
|||||||
checkForFailure(engine.getDependencies());
|
checkForFailure(engine.getDependencies());
|
||||||
}
|
}
|
||||||
} catch (DatabaseException ex) {
|
} catch (DatabaseException ex) {
|
||||||
LOGGER.log(Level.SEVERE,
|
LOGGER.log(Level.SEVERE, "Unable to connect to the dependency-check database; analysis has stopped");
|
||||||
"Unable to connect to the dependency-check database; analysis has stopped");
|
|
||||||
LOGGER.log(Level.FINE, "", ex);
|
LOGGER.log(Level.FINE, "", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -620,7 +637,8 @@ public class DependencyCheckMojo extends ReportAggregationMojo {
|
|||||||
for (MavenProject child : getAllChildren(project)) {
|
for (MavenProject child : getAllChildren(project)) {
|
||||||
deps = readDataFile(child);
|
deps = readDataFile(child);
|
||||||
if (deps == null) {
|
if (deps == null) {
|
||||||
final String msg = String.format("Unable to include information on %s in the dependency-check aggregate report", child.getName());
|
final String msg = String.format("Unable to include information on %s in the dependency-check aggregate report",
|
||||||
|
child.getName());
|
||||||
LOGGER.severe(msg);
|
LOGGER.severe(msg);
|
||||||
} else {
|
} else {
|
||||||
engine.getDependencies().addAll(deps);
|
engine.getDependencies().addAll(deps);
|
||||||
@@ -646,8 +664,7 @@ public class DependencyCheckMojo extends ReportAggregationMojo {
|
|||||||
* @return the output name
|
* @return the output name
|
||||||
*/
|
*/
|
||||||
public String getOutputName() {
|
public String getOutputName() {
|
||||||
if ("HTML".equalsIgnoreCase(this.format)
|
if ("HTML".equalsIgnoreCase(this.format) || "ALL".equalsIgnoreCase(this.format)) {
|
||||||
|| "ALL".equalsIgnoreCase(this.format)) {
|
|
||||||
return "dependency-check-report";
|
return "dependency-check-report";
|
||||||
} else if ("XML".equalsIgnoreCase(this.format)) {
|
} else if ("XML".equalsIgnoreCase(this.format)) {
|
||||||
return "dependency-check-report.xml#";
|
return "dependency-check-report.xml#";
|
||||||
@@ -740,8 +757,8 @@ public class DependencyCheckMojo extends ReportAggregationMojo {
|
|||||||
protected boolean canGenerateAggregateReport() {
|
protected boolean canGenerateAggregateReport() {
|
||||||
return isAggregate() && isLastProject();
|
return isAggregate() && isLastProject();
|
||||||
}
|
}
|
||||||
// </editor-fold>
|
|
||||||
|
|
||||||
|
// </editor-fold>
|
||||||
//<editor-fold defaultstate="collapsed" desc="Methods to fail build or show summary">
|
//<editor-fold defaultstate="collapsed" desc="Methods to fail build or show summary">
|
||||||
/**
|
/**
|
||||||
* Checks to see if a vulnerability has been identified with a CVSS score that is above the threshold set in the
|
* Checks to see if a vulnerability has been identified with a CVSS score that is above the threshold set in the
|
||||||
@@ -807,14 +824,13 @@ public class DependencyCheckMojo extends ReportAggregationMojo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (summary.length() > 0) {
|
if (summary.length() > 0) {
|
||||||
final String msg = String.format("%n%n"
|
final String msg = String.format("%n%n" + "One or more dependencies were identified with known vulnerabilities:%n%n%s"
|
||||||
+ "One or more dependencies were identified with known vulnerabilities:%n%n%s"
|
|
||||||
+ "%n%nSee the dependency-check report for more details.%n%n", summary.toString());
|
+ "%n%nSee the dependency-check report for more details.%n%n", summary.toString());
|
||||||
LOGGER.log(Level.WARNING, msg);
|
LOGGER.log(Level.WARNING, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//</editor-fold>
|
|
||||||
|
|
||||||
|
//</editor-fold>
|
||||||
//<editor-fold defaultstate="collapsed" desc="Methods to read/write the serialized data file">
|
//<editor-fold defaultstate="collapsed" desc="Methods to read/write the serialized data file">
|
||||||
/**
|
/**
|
||||||
* Writes the scan data to disk. This is used to serialize the scan data between the "check" and "aggregate" phase.
|
* Writes the scan data to disk. This is used to serialize the scan data between the "check" and "aggregate" phase.
|
||||||
|
|||||||
@@ -24,16 +24,16 @@ types that they support are detected - so specifically disabling them may not
|
|||||||
be needed.
|
be needed.
|
||||||
|
|
||||||
Property | Description | Default Value
|
Property | Description | Default Value
|
||||||
------------------------|------------------------------------|------------------
|
------------------------|---------------------------------------------------------------------------|------------------
|
||||||
archiveAnalyzerEnabled | Sets whether the Archive Analyzer will be used. | true
|
archiveAnalyzerEnabled | Sets whether the Archive Analyzer will be used. | true
|
||||||
zipExtensions | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. |
|
zipExtensions | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. |
|
||||||
jarAnalyzer | Sets whether Jar Analyzer will be used. | true
|
jarAnalyzer | Sets whether Jar Analyzer will be used. | true
|
||||||
nexusAnalyzerEnabled | Sets whether Nexus Analyzer will be used. | true
|
nexusAnalyzerEnabled | Sets whether Nexus Analyzer will be used. | true
|
||||||
nexusUrl | Defines the Nexus URL. | https://repository.sonatype.org/service/local/
|
nexusUrl | Defines the Nexus Pro Server URL. If not set the Nexus Analyzer will be disabled. |
|
||||||
nexusUsesProxy | Whether or not the defined proxy should be used when connecting to Nexus. | true
|
nexusUsesProxy | Whether or not the defined proxy should be used when connecting to Nexus. | true
|
||||||
nuspecAnalyzerEnabled | Sets whether or not the .NET Nuget Nuspec Analyzer will be used. | true
|
nuspecAnalyzerEnabled | Sets whether or not the .NET Nuget Nuspec Analyzer will be used. | true
|
||||||
assemblyAnalyzerEnabled | Sets whether or not the .NET Assembly Analyzer should be used. | true
|
assemblyAnalyzerEnabled | Sets whether or not the .NET Assembly Analyzer should be used. | true
|
||||||
pathToMono | The path to Mono for .NET assembly analysis on non-windows systems |
|
pathToMono | The path to Mono for .NET assembly analysis on non-windows systems. |
|
||||||
|
|
||||||
Advanced Configuration
|
Advanced Configuration
|
||||||
====================
|
====================
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ Copyright (c) 2014 - Jeremy Long. All Rights Reserved.
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp</groupId>
|
<groupId>org.owasp</groupId>
|
||||||
<artifactId>dependency-check-parent</artifactId>
|
<artifactId>dependency-check-parent</artifactId>
|
||||||
<version>1.2.5</version>
|
<version>1.2.6-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>dependency-check-utils</artifactId>
|
<artifactId>dependency-check-utils</artifactId>
|
||||||
@@ -249,6 +249,9 @@ Copyright (c) 2014 - Jeremy Long. All Rights Reserved.
|
|||||||
<targetJdk>1.6</targetJdk>
|
<targetJdk>1.6</targetJdk>
|
||||||
<linkXref>true</linkXref>
|
<linkXref>true</linkXref>
|
||||||
<sourceEncoding>utf-8</sourceEncoding>
|
<sourceEncoding>utf-8</sourceEncoding>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/org/owasp/dependencycheck/org/apache/**/*.java</exclude>
|
||||||
|
</excludes>
|
||||||
<rulesets>
|
<rulesets>
|
||||||
<ruleset>../src/main/config/dcrules.xml</ruleset>
|
<ruleset>../src/main/config/dcrules.xml</ruleset>
|
||||||
<ruleset>/rulesets/java/basic.xml</ruleset>
|
<ruleset>/rulesets/java/basic.xml</ruleset>
|
||||||
@@ -261,6 +264,9 @@ Copyright (c) 2014 - Jeremy Long. All Rights Reserved.
|
|||||||
<groupId>org.codehaus.mojo</groupId>
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
<artifactId>findbugs-maven-plugin</artifactId>
|
<artifactId>findbugs-maven-plugin</artifactId>
|
||||||
<version>2.5.3</version>
|
<version>2.5.3</version>
|
||||||
|
<configuration>
|
||||||
|
<onlyAnalyze>org.owasp.dependencycheck.utils.*</onlyAnalyze>
|
||||||
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
</reportPlugins>
|
</reportPlugins>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|||||||
@@ -0,0 +1,153 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signals an error condition during a build
|
||||||
|
*/
|
||||||
|
public class BuildException extends RuntimeException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -5419014565354664240L;
|
||||||
|
|
||||||
|
/** Location in the build file where the exception occurred */
|
||||||
|
private Location location = Location.UNKNOWN_LOCATION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a build exception with no descriptive information.
|
||||||
|
*/
|
||||||
|
public BuildException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an exception with the given descriptive message.
|
||||||
|
*
|
||||||
|
* @param message A description of or information about the exception.
|
||||||
|
* Should not be <code>null</code>.
|
||||||
|
*/
|
||||||
|
public BuildException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an exception with the given message and exception as
|
||||||
|
* a root cause.
|
||||||
|
*
|
||||||
|
* @param message A description of or information about the exception.
|
||||||
|
* Should not be <code>null</code> unless a cause is specified.
|
||||||
|
* @param cause The exception that might have caused this one.
|
||||||
|
* May be <code>null</code>.
|
||||||
|
*/
|
||||||
|
public BuildException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an exception with the given message and exception as
|
||||||
|
* a root cause and a location in a file.
|
||||||
|
*
|
||||||
|
* @param msg A description of or information about the exception.
|
||||||
|
* Should not be <code>null</code> unless a cause is specified.
|
||||||
|
* @param cause The exception that might have caused this one.
|
||||||
|
* May be <code>null</code>.
|
||||||
|
* @param location The location in the project file where the error
|
||||||
|
* occurred. Must not be <code>null</code>.
|
||||||
|
*/
|
||||||
|
public BuildException(String msg, Throwable cause, Location location) {
|
||||||
|
this(msg, cause);
|
||||||
|
this.location = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an exception with the given exception as a root cause.
|
||||||
|
*
|
||||||
|
* @param cause The exception that might have caused this one.
|
||||||
|
* Should not be <code>null</code>.
|
||||||
|
*/
|
||||||
|
public BuildException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an exception with the given descriptive message and a
|
||||||
|
* location in a file.
|
||||||
|
*
|
||||||
|
* @param message A description of or information about the exception.
|
||||||
|
* Should not be <code>null</code>.
|
||||||
|
* @param location The location in the project file where the error
|
||||||
|
* occurred. Must not be <code>null</code>.
|
||||||
|
*/
|
||||||
|
public BuildException(String message, Location location) {
|
||||||
|
super(message);
|
||||||
|
this.location = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an exception with the given exception as
|
||||||
|
* a root cause and a location in a file.
|
||||||
|
*
|
||||||
|
* @param cause The exception that might have caused this one.
|
||||||
|
* Should not be <code>null</code>.
|
||||||
|
* @param location The location in the project file where the error
|
||||||
|
* occurred. Must not be <code>null</code>.
|
||||||
|
*/
|
||||||
|
public BuildException(Throwable cause, Location location) {
|
||||||
|
this(cause);
|
||||||
|
this.location = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the nested exception, if any.
|
||||||
|
*
|
||||||
|
* @return the nested exception, or <code>null</code> if no
|
||||||
|
* exception is associated with this one
|
||||||
|
* @deprecated Use {@link #getCause} instead.
|
||||||
|
*/
|
||||||
|
public Throwable getException() {
|
||||||
|
return getCause();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the location of the error and the error message.
|
||||||
|
*
|
||||||
|
* @return the location of the error and the error message
|
||||||
|
*/
|
||||||
|
public String toString() {
|
||||||
|
return location.toString() + getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the file location where the error occurred.
|
||||||
|
*
|
||||||
|
* @param location The file location where the error occurred.
|
||||||
|
* Must not be <code>null</code>.
|
||||||
|
*/
|
||||||
|
public void setLocation(Location location) {
|
||||||
|
this.location = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the file location where the error occurred.
|
||||||
|
*
|
||||||
|
* @return the file location where the error occurred.
|
||||||
|
*/
|
||||||
|
public Location getLocation() {
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface used to describe the actions required of any type of
|
||||||
|
* directory scanner.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface FileScanner {
|
||||||
|
/**
|
||||||
|
* Adds default exclusions to the current exclusions set.
|
||||||
|
*/
|
||||||
|
void addDefaultExcludes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the base directory to be scanned.
|
||||||
|
* This is the directory which is scanned recursively.
|
||||||
|
*
|
||||||
|
* @return the base directory to be scanned
|
||||||
|
*/
|
||||||
|
File getBasedir();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the names of the directories which matched at least one of the
|
||||||
|
* include patterns and at least one of the exclude patterns.
|
||||||
|
* The names are relative to the base directory.
|
||||||
|
*
|
||||||
|
* @return the names of the directories which matched at least one of the
|
||||||
|
* include patterns and at least one of the exclude patterns.
|
||||||
|
*/
|
||||||
|
String[] getExcludedDirectories();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the names of the files which matched at least one of the
|
||||||
|
* include patterns and at least one of the exclude patterns.
|
||||||
|
* The names are relative to the base directory.
|
||||||
|
*
|
||||||
|
* @return the names of the files which matched at least one of the
|
||||||
|
* include patterns and at least one of the exclude patterns.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
String[] getExcludedFiles();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the names of the directories which matched at least one of the
|
||||||
|
* include patterns and none of the exclude patterns.
|
||||||
|
* The names are relative to the base directory.
|
||||||
|
*
|
||||||
|
* @return the names of the directories which matched at least one of the
|
||||||
|
* include patterns and none of the exclude patterns.
|
||||||
|
*/
|
||||||
|
String[] getIncludedDirectories();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the names of the files which matched at least one of the
|
||||||
|
* include patterns and none of the exclude patterns.
|
||||||
|
* The names are relative to the base directory.
|
||||||
|
*
|
||||||
|
* @return the names of the files which matched at least one of the
|
||||||
|
* include patterns and none of the exclude patterns.
|
||||||
|
*/
|
||||||
|
String[] getIncludedFiles();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the names of the directories which matched none of the include
|
||||||
|
* patterns. The names are relative to the base directory.
|
||||||
|
*
|
||||||
|
* @return the names of the directories which matched none of the include
|
||||||
|
* patterns.
|
||||||
|
*/
|
||||||
|
String[] getNotIncludedDirectories();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the names of the files which matched none of the include
|
||||||
|
* patterns. The names are relative to the base directory.
|
||||||
|
*
|
||||||
|
* @return the names of the files which matched none of the include
|
||||||
|
* patterns.
|
||||||
|
*/
|
||||||
|
String[] getNotIncludedFiles();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scans the base directory for files which match at least one include
|
||||||
|
* pattern and don't match any exclude patterns.
|
||||||
|
*
|
||||||
|
* @exception IllegalStateException if the base directory was set
|
||||||
|
* incorrectly (i.e. if it is <code>null</code>, doesn't exist,
|
||||||
|
* or isn't a directory).
|
||||||
|
*/
|
||||||
|
void scan() throws IllegalStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the base directory to be scanned. This is the directory which is
|
||||||
|
* scanned recursively. All '/' and '\' characters should be replaced by
|
||||||
|
* <code>File.separatorChar</code>, so the separator used need not match
|
||||||
|
* <code>File.separatorChar</code>.
|
||||||
|
*
|
||||||
|
* @param basedir The base directory to scan.
|
||||||
|
* Must not be <code>null</code>.
|
||||||
|
*/
|
||||||
|
void setBasedir(String basedir);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the base directory to be scanned. This is the directory which is
|
||||||
|
* scanned recursively.
|
||||||
|
*
|
||||||
|
* @param basedir The base directory for scanning.
|
||||||
|
* Should not be <code>null</code>.
|
||||||
|
*/
|
||||||
|
void setBasedir(File basedir);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the list of exclude patterns to use.
|
||||||
|
*
|
||||||
|
* @param excludes A list of exclude patterns.
|
||||||
|
* May be <code>null</code>, indicating that no files
|
||||||
|
* should be excluded. If a non-<code>null</code> list is
|
||||||
|
* given, all elements must be non-<code>null</code>.
|
||||||
|
*/
|
||||||
|
void setExcludes(String[] excludes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the list of include patterns to use.
|
||||||
|
*
|
||||||
|
* @param includes A list of include patterns.
|
||||||
|
* May be <code>null</code>, indicating that all files
|
||||||
|
* should be included. If a non-<code>null</code>
|
||||||
|
* list is given, all elements must be
|
||||||
|
* non-<code>null</code>.
|
||||||
|
*/
|
||||||
|
void setIncludes(String[] includes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether or not the file system should be regarded as case sensitive.
|
||||||
|
*
|
||||||
|
* @param isCaseSensitive whether or not the file system should be
|
||||||
|
* regarded as a case sensitive one
|
||||||
|
*/
|
||||||
|
void setCaseSensitive(boolean isCaseSensitive);
|
||||||
|
}
|
||||||
@@ -0,0 +1,178 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import org.owasp.dependencycheck.org.apache.tools.ant.util.FileUtils;
|
||||||
|
import org.xml.sax.Locator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the location of a piece of text within a file (file name,
|
||||||
|
* line number and column number). Note that the column number is
|
||||||
|
* currently ignored.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Location implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** Name of the file. */
|
||||||
|
private final String fileName;
|
||||||
|
/** Line number within the file. */
|
||||||
|
private final int lineNumber;
|
||||||
|
/** Column number within the file. */
|
||||||
|
private final int columnNumber;
|
||||||
|
|
||||||
|
/** Location to use when one is needed but no information is available */
|
||||||
|
public static final Location UNKNOWN_LOCATION = new Location();
|
||||||
|
|
||||||
|
private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an "unknown" location.
|
||||||
|
*/
|
||||||
|
private Location() {
|
||||||
|
this(null, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a location consisting of a file name but no line number or
|
||||||
|
* column number.
|
||||||
|
*
|
||||||
|
* @param fileName The name of the file. May be <code>null</code>,
|
||||||
|
* in which case the location is equivalent to
|
||||||
|
* {@link #UNKNOWN_LOCATION UNKNOWN_LOCATION}.
|
||||||
|
*/
|
||||||
|
public Location(String fileName) {
|
||||||
|
this(fileName, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a location from the SAX locator using the system ID as
|
||||||
|
* the filename.
|
||||||
|
*
|
||||||
|
* @param loc Must not be <code>null</code>.
|
||||||
|
*
|
||||||
|
* @since Ant 1.6
|
||||||
|
*/
|
||||||
|
public Location(Locator loc) {
|
||||||
|
this(loc.getSystemId(), loc.getLineNumber(), loc.getColumnNumber());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a location consisting of a file name, line number and
|
||||||
|
* column number.
|
||||||
|
*
|
||||||
|
* @param fileName The name of the file. May be <code>null</code>,
|
||||||
|
* in which case the location is equivalent to
|
||||||
|
* {@link #UNKNOWN_LOCATION UNKNOWN_LOCATION}.
|
||||||
|
*
|
||||||
|
* @param lineNumber Line number within the file. Use 0 for unknown
|
||||||
|
* positions within a file.
|
||||||
|
* @param columnNumber Column number within the line.
|
||||||
|
*/
|
||||||
|
public Location(String fileName, int lineNumber, int columnNumber) {
|
||||||
|
if (fileName != null && fileName.startsWith("file:")) {
|
||||||
|
this.fileName = FILE_UTILS.fromURI(fileName);
|
||||||
|
} else {
|
||||||
|
this.fileName = fileName;
|
||||||
|
}
|
||||||
|
this.lineNumber = lineNumber;
|
||||||
|
this.columnNumber = columnNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the filename portion of the location
|
||||||
|
* @since Ant 1.6
|
||||||
|
*/
|
||||||
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the line number
|
||||||
|
* @since Ant 1.6
|
||||||
|
*/
|
||||||
|
public int getLineNumber() {
|
||||||
|
return lineNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the column number
|
||||||
|
* @since Ant 1.7
|
||||||
|
*/
|
||||||
|
public int getColumnNumber() {
|
||||||
|
return columnNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the file name, line number, a colon and a trailing space.
|
||||||
|
* An error message can be appended easily. For unknown locations, an
|
||||||
|
* empty string is returned.
|
||||||
|
*
|
||||||
|
* @return a String of the form <code>"fileName:lineNumber: "</code>
|
||||||
|
* if both file name and line number are known,
|
||||||
|
* <code>"fileName: "</code> if only the file name is known,
|
||||||
|
* and the empty string for unknown locations.
|
||||||
|
*/
|
||||||
|
public String toString() {
|
||||||
|
StringBuffer buf = new StringBuffer();
|
||||||
|
|
||||||
|
if (fileName != null) {
|
||||||
|
buf.append(fileName);
|
||||||
|
|
||||||
|
if (lineNumber != 0) {
|
||||||
|
buf.append(":");
|
||||||
|
buf.append(lineNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.append(": ");
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Equality operation.
|
||||||
|
* @param other the object to compare to.
|
||||||
|
* @return true if the other object contains the same information
|
||||||
|
* as this object.
|
||||||
|
* @since Ant 1.6.3
|
||||||
|
*/
|
||||||
|
public boolean equals(Object other) {
|
||||||
|
if (this == other) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (other == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(other.getClass() == getClass())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return toString().equals(other.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hash operation.
|
||||||
|
* @return a hash code value for this location.
|
||||||
|
* @since Ant 1.6.3
|
||||||
|
*/
|
||||||
|
public int hashCode() {
|
||||||
|
return toString().hashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
import org.owasp.dependencycheck.org.apache.tools.ant.taskdefs.condition.Os;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Path tokenizer takes a path and returns the components that make up
|
||||||
|
* that path.
|
||||||
|
*
|
||||||
|
* The path can use path separators of either ':' or ';' and file separators
|
||||||
|
* of either '/' or '\'.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class PathTokenizer {
|
||||||
|
/**
|
||||||
|
* A tokenizer to break the string up based on the ':' or ';' separators.
|
||||||
|
*/
|
||||||
|
private StringTokenizer tokenizer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A String which stores any path components which have been read ahead
|
||||||
|
* due to DOS filesystem compensation.
|
||||||
|
*/
|
||||||
|
private String lookahead = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean that determines if we are running on Novell NetWare, which
|
||||||
|
* exhibits slightly different path name characteristics (multi-character
|
||||||
|
* volume / drive names)
|
||||||
|
*/
|
||||||
|
private boolean onNetWare = Os.isFamily("netware");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag to indicate whether or not we are running on a platform with a
|
||||||
|
* DOS style filesystem
|
||||||
|
*/
|
||||||
|
private boolean dosStyleFilesystem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a path tokenizer for the specified path.
|
||||||
|
*
|
||||||
|
* @param path The path to tokenize. Must not be <code>null</code>.
|
||||||
|
*/
|
||||||
|
public PathTokenizer(String path) {
|
||||||
|
if (onNetWare) {
|
||||||
|
// For NetWare, use the boolean=true mode, so we can use delimiter
|
||||||
|
// information to make a better decision later.
|
||||||
|
tokenizer = new StringTokenizer(path, ":;", true);
|
||||||
|
} else {
|
||||||
|
// on Windows and Unix, we can ignore delimiters and still have
|
||||||
|
// enough information to tokenize correctly.
|
||||||
|
tokenizer = new StringTokenizer(path, ":;", false);
|
||||||
|
}
|
||||||
|
dosStyleFilesystem = File.pathSeparatorChar == ';';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests if there are more path elements available from this tokenizer's
|
||||||
|
* path. If this method returns <code>true</code>, then a subsequent call
|
||||||
|
* to nextToken will successfully return a token.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if and only if there is at least one token
|
||||||
|
* in the string after the current position; <code>false</code> otherwise.
|
||||||
|
*/
|
||||||
|
public boolean hasMoreTokens() {
|
||||||
|
if (lookahead != null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tokenizer.hasMoreTokens();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the next path element from this tokenizer.
|
||||||
|
*
|
||||||
|
* @return the next path element from this tokenizer.
|
||||||
|
*
|
||||||
|
* @exception NoSuchElementException if there are no more elements in this
|
||||||
|
* tokenizer's path.
|
||||||
|
*/
|
||||||
|
public String nextToken() throws NoSuchElementException {
|
||||||
|
String token = null;
|
||||||
|
if (lookahead != null) {
|
||||||
|
token = lookahead;
|
||||||
|
lookahead = null;
|
||||||
|
} else {
|
||||||
|
token = tokenizer.nextToken().trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!onNetWare) {
|
||||||
|
if (token.length() == 1 && Character.isLetter(token.charAt(0))
|
||||||
|
&& dosStyleFilesystem
|
||||||
|
&& tokenizer.hasMoreTokens()) {
|
||||||
|
// we are on a dos style system so this path could be a drive
|
||||||
|
// spec. We look at the next token
|
||||||
|
String nextToken = tokenizer.nextToken().trim();
|
||||||
|
if (nextToken.startsWith("\\") || nextToken.startsWith("/")) {
|
||||||
|
// we know we are on a DOS style platform and the next path
|
||||||
|
// starts with a slash or backslash, so we know this is a
|
||||||
|
// drive spec
|
||||||
|
token += ":" + nextToken;
|
||||||
|
} else {
|
||||||
|
// store the token just read for next time
|
||||||
|
lookahead = nextToken;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// we are on NetWare, tokenizing is handled a little differently,
|
||||||
|
// due to the fact that NetWare has multiple-character volume names.
|
||||||
|
if (token.equals(File.pathSeparator) || token.equals(":")) {
|
||||||
|
// ignore ";" and get the next token
|
||||||
|
token = tokenizer.nextToken().trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tokenizer.hasMoreTokens()) {
|
||||||
|
// this path could be a drive spec, so look at the next token
|
||||||
|
String nextToken = tokenizer.nextToken().trim();
|
||||||
|
|
||||||
|
// make sure we aren't going to get the path separator next
|
||||||
|
if (!nextToken.equals(File.pathSeparator)) {
|
||||||
|
if (nextToken.equals(":")) {
|
||||||
|
if (!token.startsWith("/") && !token.startsWith("\\")
|
||||||
|
&& !token.startsWith(".")
|
||||||
|
&& !token.startsWith("..")) {
|
||||||
|
// it indeed is a drive spec, get the next bit
|
||||||
|
String oneMore = tokenizer.nextToken().trim();
|
||||||
|
if (!oneMore.equals(File.pathSeparator)) {
|
||||||
|
token += ":" + oneMore;
|
||||||
|
} else {
|
||||||
|
token += ":";
|
||||||
|
lookahead = oneMore;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// implicit else: ignore the ':' since we have either a
|
||||||
|
// UNIX or a relative path
|
||||||
|
} else {
|
||||||
|
// store the token just read for next time
|
||||||
|
lookahead = nextToken;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,161 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for components of a project, including tasks and data types. Provides common facilities.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class ProjectComponent implements Cloneable {
|
||||||
|
|
||||||
|
// // CheckStyle:VisibilityModifier OFF - bc
|
||||||
|
// /**
|
||||||
|
// * Project object of this component.
|
||||||
|
// * @deprecated since 1.6.x.
|
||||||
|
// * You should not be directly accessing this variable directly.
|
||||||
|
// * You should access project object via the getProject()
|
||||||
|
// * or setProject() accessor/mutators.
|
||||||
|
// */
|
||||||
|
// protected Project project;
|
||||||
|
/**
|
||||||
|
* Location within the build file of this task definition.
|
||||||
|
*
|
||||||
|
* @deprecated since 1.6.x. You should not be accessing this variable directly. Please use the
|
||||||
|
* {@link #getLocation()} method.
|
||||||
|
*/
|
||||||
|
protected Location location = Location.UNKNOWN_LOCATION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of this component, if any.
|
||||||
|
*
|
||||||
|
* @deprecated since 1.6.x. You should not be accessing this variable directly.
|
||||||
|
*/
|
||||||
|
protected String description;
|
||||||
|
// CheckStyle:VisibilityModifier ON
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sole constructor.
|
||||||
|
*/
|
||||||
|
public ProjectComponent() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Sets the project object of this component. This method is used by
|
||||||
|
// * Project when a component is added to it so that the component has
|
||||||
|
// * access to the functions of the project. It should not be used
|
||||||
|
// * for any other purpose.
|
||||||
|
// *
|
||||||
|
// * @param project Project in whose scope this component belongs.
|
||||||
|
// * Must not be <code>null</code>.
|
||||||
|
// */
|
||||||
|
// public void setProject(Project project) {
|
||||||
|
// this.project = project;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Returns the project to which this component belongs.
|
||||||
|
// *
|
||||||
|
// * @return the components's project.
|
||||||
|
// */
|
||||||
|
// public Project getProject() {
|
||||||
|
// return project;
|
||||||
|
// }
|
||||||
|
/**
|
||||||
|
* Returns the file/location where this task was defined.
|
||||||
|
*
|
||||||
|
* @return the file/location where this task was defined. Should not return <code>null</code>.
|
||||||
|
* Location.UNKNOWN_LOCATION is used for unknown locations.
|
||||||
|
*
|
||||||
|
* @see Location#UNKNOWN_LOCATION
|
||||||
|
*/
|
||||||
|
public Location getLocation() {
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the file/location where this task was defined.
|
||||||
|
*
|
||||||
|
* @param location The file/location where this task was defined. Should not be <code>null</code>--use
|
||||||
|
* Location.UNKNOWN_LOCATION if the location isn't known.
|
||||||
|
*
|
||||||
|
* @see Location#UNKNOWN_LOCATION
|
||||||
|
*/
|
||||||
|
public void setLocation(Location location) {
|
||||||
|
this.location = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a description of the current action. This may be used for logging purposes.
|
||||||
|
*
|
||||||
|
* @param desc Description of the current action. May be <code>null</code>, indicating that no description is
|
||||||
|
* available.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void setDescription(String desc) {
|
||||||
|
description = desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the description of the current action.
|
||||||
|
*
|
||||||
|
* @return the description of the current action, or <code>null</code> if no description is available.
|
||||||
|
*/
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a message with the default (INFO) priority.
|
||||||
|
*
|
||||||
|
* @param msg The message to be logged. Should not be <code>null</code>.
|
||||||
|
*/
|
||||||
|
public void log(String msg) {
|
||||||
|
// log(msg, Project.MSG_INFO);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a message with the given priority.
|
||||||
|
*
|
||||||
|
* @param msg The message to be logged. Should not be <code>null</code>.
|
||||||
|
* @param msgLevel the message priority at which this message is to be logged.
|
||||||
|
*/
|
||||||
|
public void log(String msg, int msgLevel) {
|
||||||
|
// if (getProject() != null) {
|
||||||
|
// getProject().log(msg, msgLevel);
|
||||||
|
// } else {
|
||||||
|
// // 'reasonable' default, if the component is used without
|
||||||
|
// // a Project ( for example as a standalone Bean ).
|
||||||
|
// // Most ant components can be used this way.
|
||||||
|
// if (msgLevel <= Project.MSG_INFO) {
|
||||||
|
// System.err.println(msg);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since Ant 1.7
|
||||||
|
* @return a shallow copy of this projectcomponent.
|
||||||
|
* @throws CloneNotSupportedException does not happen, but is declared to allow subclasses to do so.
|
||||||
|
*/
|
||||||
|
public Object clone() throws CloneNotSupportedException {
|
||||||
|
ProjectComponent pc = (ProjectComponent) super.clone();
|
||||||
|
pc.setLocation(getLocation());
|
||||||
|
//pc.setProject(getProject());
|
||||||
|
return pc;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,530 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.launch;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FilenameFilter;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.text.CharacterIterator;
|
||||||
|
import java.text.StringCharacterIterator;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import org.owasp.dependencycheck.org.apache.tools.ant.util.FileUtils;
|
||||||
|
|
||||||
|
// CheckStyle:LineLengthCheck OFF - urls are long!
|
||||||
|
/**
|
||||||
|
* The Locator is a utility class which is used to find certain items
|
||||||
|
* in the environment.
|
||||||
|
*
|
||||||
|
* It is used at boot time in the launcher, and cannot make use of any of Ant's other classes.
|
||||||
|
*
|
||||||
|
* This is a surprisingly brittle piece of code, and has had lots of bugs filed against it.
|
||||||
|
* {@link <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=42275">running ant off a network share can cause Ant to fail</a>}
|
||||||
|
* {@link <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=8031">use File.toURI().toURL().toExternalForm()</a>}
|
||||||
|
* {@link <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=42222">Locator implementation not encoding URI strings properly: spaces in paths</a>}
|
||||||
|
* It also breaks Eclipse 3.3 Betas
|
||||||
|
* {@link <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=183283">Exception if installation path has spaces</a>}
|
||||||
|
*
|
||||||
|
* Be very careful when making changes to this class, as a break will upset a lot of people.
|
||||||
|
* @since Ant 1.6
|
||||||
|
*/
|
||||||
|
// CheckStyle:LineLengthCheck ON - urls are long!
|
||||||
|
public final class Locator {
|
||||||
|
|
||||||
|
private static final int NIBBLE = 4;
|
||||||
|
private static final int NIBBLE_MASK = 0xF;
|
||||||
|
|
||||||
|
private static final int ASCII_SIZE = 128;
|
||||||
|
|
||||||
|
private static final int BYTE_SIZE = 256;
|
||||||
|
|
||||||
|
private static final int WORD = 16;
|
||||||
|
|
||||||
|
private static final int SPACE = 0x20;
|
||||||
|
private static final int DEL = 0x7F;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* encoding used to represent URIs
|
||||||
|
*/
|
||||||
|
public static final String URI_ENCODING = "UTF-8";
|
||||||
|
// stolen from org.apache.xerces.impl.XMLEntityManager#getUserDir()
|
||||||
|
// of the Xerces-J team
|
||||||
|
// which ASCII characters need to be escaped
|
||||||
|
private static boolean[] gNeedEscaping = new boolean[ASCII_SIZE];
|
||||||
|
// the first hex character if a character needs to be escaped
|
||||||
|
private static char[] gAfterEscaping1 = new char[ASCII_SIZE];
|
||||||
|
// the second hex character if a character needs to be escaped
|
||||||
|
private static char[] gAfterEscaping2 = new char[ASCII_SIZE];
|
||||||
|
private static char[] gHexChs = {'0', '1', '2', '3', '4', '5', '6', '7',
|
||||||
|
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||||
|
/** Error string used when an invalid uri is seen */
|
||||||
|
public static final String ERROR_NOT_FILE_URI
|
||||||
|
= "Can only handle valid file: URIs, not ";
|
||||||
|
|
||||||
|
// initialize the above 3 arrays
|
||||||
|
static {
|
||||||
|
for (int i = 0; i < SPACE; i++) {
|
||||||
|
gNeedEscaping[i] = true;
|
||||||
|
gAfterEscaping1[i] = gHexChs[i >> NIBBLE];
|
||||||
|
gAfterEscaping2[i] = gHexChs[i & NIBBLE_MASK];
|
||||||
|
}
|
||||||
|
gNeedEscaping[DEL] = true;
|
||||||
|
gAfterEscaping1[DEL] = '7';
|
||||||
|
gAfterEscaping2[DEL] = 'F';
|
||||||
|
char[] escChs = {' ', '<', '>', '#', '%', '"', '{', '}',
|
||||||
|
'|', '\\', '^', '~', '[', ']', '`'};
|
||||||
|
int len = escChs.length;
|
||||||
|
char ch;
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
ch = escChs[i];
|
||||||
|
gNeedEscaping[ch] = true;
|
||||||
|
gAfterEscaping1[ch] = gHexChs[ch >> NIBBLE];
|
||||||
|
gAfterEscaping2[ch] = gHexChs[ch & NIBBLE_MASK];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Not instantiable
|
||||||
|
*/
|
||||||
|
private Locator() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the directory or jar file the class has been loaded from.
|
||||||
|
*
|
||||||
|
* @param c the class whose location is required.
|
||||||
|
* @return the file or jar with the class or null if we cannot
|
||||||
|
* determine the location.
|
||||||
|
*
|
||||||
|
* @since Ant 1.6
|
||||||
|
*/
|
||||||
|
public static File getClassSource(Class<?> c) {
|
||||||
|
String classResource = c.getName().replace('.', '/') + ".class";
|
||||||
|
return getResourceSource(c.getClassLoader(), classResource);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the directory or jar a given resource has been loaded from.
|
||||||
|
*
|
||||||
|
* @param c the classloader to be consulted for the source.
|
||||||
|
* @param resource the resource whose location is required.
|
||||||
|
*
|
||||||
|
* @return the file with the resource source or null if
|
||||||
|
* we cannot determine the location.
|
||||||
|
*
|
||||||
|
* @since Ant 1.6
|
||||||
|
*/
|
||||||
|
public static File getResourceSource(ClassLoader c, String resource) {
|
||||||
|
if (c == null) {
|
||||||
|
c = Locator.class.getClassLoader();
|
||||||
|
}
|
||||||
|
URL url = null;
|
||||||
|
if (c == null) {
|
||||||
|
url = ClassLoader.getSystemResource(resource);
|
||||||
|
} else {
|
||||||
|
url = c.getResource(resource);
|
||||||
|
}
|
||||||
|
if (url != null) {
|
||||||
|
String u = url.toString();
|
||||||
|
try {
|
||||||
|
if (u.startsWith("jar:file:")) {
|
||||||
|
return new File(fromJarURI(u));
|
||||||
|
} else if (u.startsWith("file:")) {
|
||||||
|
int tail = u.indexOf(resource);
|
||||||
|
String dirName = u.substring(0, tail);
|
||||||
|
return new File(fromURI(dirName));
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
//unable to determine the URI for reasons unknown.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a file path from a <code>file:</code> URI.
|
||||||
|
*
|
||||||
|
* <p>Will be an absolute path if the given URI is absolute.</p>
|
||||||
|
*
|
||||||
|
* <p>Prior to Java 1.4,<!-- TODO is JDK version actually relevant? -->
|
||||||
|
* swallows '%' that are not followed by two characters.</p>
|
||||||
|
*
|
||||||
|
* See <a href="http://www.w3.org/TR/xml11/#dt-sysid">dt-sysid</a>
|
||||||
|
* which makes some mention of how
|
||||||
|
* characters not supported by URI Reference syntax should be escaped.
|
||||||
|
*
|
||||||
|
* @param uri the URI designating a file in the local filesystem.
|
||||||
|
* @return the local file system path for the file.
|
||||||
|
* @throws IllegalArgumentException if the URI is malformed or not a legal file: URL
|
||||||
|
* @since Ant 1.6
|
||||||
|
*/
|
||||||
|
public static String fromURI(String uri) {
|
||||||
|
return fromURIJava13(uri);
|
||||||
|
// #buzilla8031: first try Java 1.4.
|
||||||
|
// TODO should use java.net.URI now that we can rely on 1.4...
|
||||||
|
// but check for UNC-related regressions, e.g. #42275
|
||||||
|
// (and remember that \\server\share\file -> file:////server/share/file
|
||||||
|
// rather than -> file://server/share/file as it should;
|
||||||
|
// fixed only in JDK 7's java.nio.file.Path.toUri)
|
||||||
|
// return fromUriJava14(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Java1.4+ code to extract the path from the URI.
|
||||||
|
* @param uri
|
||||||
|
* @return null if a conversion was not possible
|
||||||
|
*/
|
||||||
|
/* currently unused:
|
||||||
|
private static String fromUriJava14(String uri) {
|
||||||
|
// Also check for properly formed URIs. Ant formerly recommended using
|
||||||
|
// nonsense URIs such as "file:./foo.xml" in XML includes. You shouldn't
|
||||||
|
// do that (just "foo.xml" is correct) but for compatibility we special-case
|
||||||
|
// things when the path is not absolute, and fall back to the old parsing behavior.
|
||||||
|
if (uri.startsWith("file:/")) {
|
||||||
|
try {
|
||||||
|
File f = new File(URI.create(encodeURI(uri)));
|
||||||
|
//bug #42227 forgot to decode before returning
|
||||||
|
return decodeUri(f.getAbsolutePath());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// Bad URI, pass this on.
|
||||||
|
// no, this is downgraded to a warning after various
|
||||||
|
// JRE bugs surfaced. Hand off
|
||||||
|
// to our built in code on a failure
|
||||||
|
//throw new IllegalArgumentException(
|
||||||
|
// "Bad URI " + uri + ":" + e.getMessage(), e);
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Unexpected exception? Should not happen.
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param uri uri to expand
|
||||||
|
* @return the decoded URI
|
||||||
|
* @since Ant1.7.1
|
||||||
|
*/
|
||||||
|
private static String fromURIJava13(String uri) {
|
||||||
|
// Fallback method for Java 1.3 or earlier.
|
||||||
|
|
||||||
|
URL url = null;
|
||||||
|
try {
|
||||||
|
url = new URL(uri);
|
||||||
|
} catch (MalformedURLException emYouEarlEx) {
|
||||||
|
// Ignore malformed exception
|
||||||
|
}
|
||||||
|
if (url == null || !("file".equals(url.getProtocol()))) {
|
||||||
|
throw new IllegalArgumentException(ERROR_NOT_FILE_URI + uri);
|
||||||
|
}
|
||||||
|
StringBuffer buf = new StringBuffer(url.getHost());
|
||||||
|
if (buf.length() > 0) {
|
||||||
|
buf.insert(0, File.separatorChar).insert(0, File.separatorChar);
|
||||||
|
}
|
||||||
|
String file = url.getFile();
|
||||||
|
int queryPos = file.indexOf('?');
|
||||||
|
buf.append((queryPos < 0) ? file : file.substring(0, queryPos));
|
||||||
|
|
||||||
|
uri = buf.toString().replace('/', File.separatorChar);
|
||||||
|
|
||||||
|
if (File.pathSeparatorChar == ';' && uri.startsWith("\\") && uri.length() > 2
|
||||||
|
&& Character.isLetter(uri.charAt(1)) && uri.lastIndexOf(':') > -1) {
|
||||||
|
uri = uri.substring(1);
|
||||||
|
}
|
||||||
|
String path = null;
|
||||||
|
try {
|
||||||
|
path = decodeUri(uri);
|
||||||
|
//consider adding the current directory. This is not done when
|
||||||
|
//the path is a UNC name
|
||||||
|
String cwd = System.getProperty("user.dir");
|
||||||
|
int posi = cwd.indexOf(':');
|
||||||
|
boolean pathStartsWithFileSeparator = path.startsWith(File.separator);
|
||||||
|
boolean pathStartsWithUNC = path.startsWith("" + File.separator + File.separator);
|
||||||
|
if ((posi > 0) && pathStartsWithFileSeparator && !pathStartsWithUNC) {
|
||||||
|
path = cwd.substring(0, posi + 1) + path;
|
||||||
|
}
|
||||||
|
} catch (UnsupportedEncodingException exc) {
|
||||||
|
// not sure whether this is clean, but this method is
|
||||||
|
// declared not to throw exceptions.
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Could not convert URI " + uri + " to path: "
|
||||||
|
+ exc.getMessage());
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crack a JAR URI.
|
||||||
|
* This method is public for testing; we may delete it without any warning -it is not part of Ant's stable API.
|
||||||
|
* @param uri uri to expand; contains jar: somewhere in it
|
||||||
|
* @return the decoded URI
|
||||||
|
* @since Ant1.7.1
|
||||||
|
*/
|
||||||
|
public static String fromJarURI(String uri) {
|
||||||
|
int pling = uri.indexOf("!/");
|
||||||
|
String jarName = uri.substring("jar:".length(), pling);
|
||||||
|
return fromURI(jarName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes an Uri with % characters.
|
||||||
|
* The URI is escaped
|
||||||
|
* @param uri String with the uri possibly containing % characters.
|
||||||
|
* @return The decoded Uri
|
||||||
|
* @throws UnsupportedEncodingException if UTF-8 is not available
|
||||||
|
* @since Ant 1.7
|
||||||
|
*/
|
||||||
|
public static String decodeUri(String uri) throws UnsupportedEncodingException {
|
||||||
|
if (uri.indexOf('%') == -1) {
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
ByteArrayOutputStream sb = new ByteArrayOutputStream(uri.length());
|
||||||
|
CharacterIterator iter = new StringCharacterIterator(uri);
|
||||||
|
for (char c = iter.first(); c != CharacterIterator.DONE;
|
||||||
|
c = iter.next()) {
|
||||||
|
if (c == '%') {
|
||||||
|
char c1 = iter.next();
|
||||||
|
if (c1 != CharacterIterator.DONE) {
|
||||||
|
int i1 = Character.digit(c1, WORD);
|
||||||
|
char c2 = iter.next();
|
||||||
|
if (c2 != CharacterIterator.DONE) {
|
||||||
|
int i2 = Character.digit(c2, WORD);
|
||||||
|
sb.write((char) ((i1 << NIBBLE) + i2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (c >= 0x0000 && c < 0x0080) {
|
||||||
|
sb.write(c);
|
||||||
|
} else { // #50543
|
||||||
|
byte[] bytes = String.valueOf(c).getBytes(URI_ENCODING);
|
||||||
|
sb.write(bytes, 0, bytes.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.toString(URI_ENCODING);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes an Uri with % characters.
|
||||||
|
* The URI is escaped
|
||||||
|
* @param path String to encode.
|
||||||
|
* @return The encoded string, according to URI norms
|
||||||
|
* @throws UnsupportedEncodingException if UTF-8 is not available
|
||||||
|
* @since Ant 1.7
|
||||||
|
*/
|
||||||
|
public static String encodeURI(String path) throws UnsupportedEncodingException {
|
||||||
|
int i = 0;
|
||||||
|
int len = path.length();
|
||||||
|
int ch = 0;
|
||||||
|
StringBuffer sb = null;
|
||||||
|
for (; i < len; i++) {
|
||||||
|
ch = path.charAt(i);
|
||||||
|
// if it's not an ASCII character, break here, and use UTF-8 encoding
|
||||||
|
if (ch >= ASCII_SIZE) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (gNeedEscaping[ch]) {
|
||||||
|
if (sb == null) {
|
||||||
|
sb = new StringBuffer(path.substring(0, i));
|
||||||
|
}
|
||||||
|
sb.append('%');
|
||||||
|
sb.append(gAfterEscaping1[ch]);
|
||||||
|
sb.append(gAfterEscaping2[ch]);
|
||||||
|
// record the fact that it's escaped
|
||||||
|
} else if (sb != null) {
|
||||||
|
sb.append((char) ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we saw some non-ascii character
|
||||||
|
if (i < len) {
|
||||||
|
if (sb == null) {
|
||||||
|
sb = new StringBuffer(path.substring(0, i));
|
||||||
|
}
|
||||||
|
// get UTF-8 bytes for the remaining sub-string
|
||||||
|
byte[] bytes = null;
|
||||||
|
byte b;
|
||||||
|
bytes = path.substring(i).getBytes(URI_ENCODING);
|
||||||
|
len = bytes.length;
|
||||||
|
|
||||||
|
// for each byte
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
b = bytes[i];
|
||||||
|
// for non-ascii character: make it positive, then escape
|
||||||
|
if (b < 0) {
|
||||||
|
ch = b + BYTE_SIZE;
|
||||||
|
sb.append('%');
|
||||||
|
sb.append(gHexChs[ch >> NIBBLE]);
|
||||||
|
sb.append(gHexChs[ch & NIBBLE_MASK]);
|
||||||
|
} else if (gNeedEscaping[b]) {
|
||||||
|
sb.append('%');
|
||||||
|
sb.append(gAfterEscaping1[b]);
|
||||||
|
sb.append(gAfterEscaping2[b]);
|
||||||
|
} else {
|
||||||
|
sb.append((char) b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb == null ? path : sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a File to a URL.
|
||||||
|
* File.toURL() does not encode characters like #.
|
||||||
|
* File.toURI() has been introduced in java 1.4, so
|
||||||
|
* Ant cannot use it (except by reflection) <!-- TODO no longer true -->
|
||||||
|
* FileUtils.toURI() cannot be used by Locator.java
|
||||||
|
* Implemented this way.
|
||||||
|
* File.toURL() adds file: and changes '\' to '/' for dos OSes
|
||||||
|
* encodeURI converts characters like ' ' and '#' to %DD
|
||||||
|
* @param file the file to convert
|
||||||
|
* @return URL the converted File
|
||||||
|
* @throws MalformedURLException on error
|
||||||
|
* @deprecated since 1.9, use {@link FileUtils#getFileURL(File)}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public static URL fileToURL(File file)
|
||||||
|
throws MalformedURLException {
|
||||||
|
return new URL(file.toURI().toASCIIString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the File necessary to load the Sun compiler tools. If the classes
|
||||||
|
* are available to this class, then no additional URL is required and
|
||||||
|
* null is returned. This may be because the classes are explicitly in the
|
||||||
|
* class path or provided by the JVM directly.
|
||||||
|
*
|
||||||
|
* @return the tools jar as a File if required, null otherwise.
|
||||||
|
*/
|
||||||
|
public static File getToolsJar() {
|
||||||
|
// firstly check if the tools jar is already in the classpath
|
||||||
|
boolean toolsJarAvailable = false;
|
||||||
|
try {
|
||||||
|
// just check whether this throws an exception
|
||||||
|
Class.forName("com.sun.tools.javac.Main");
|
||||||
|
toolsJarAvailable = true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
try {
|
||||||
|
Class.forName("sun.tools.javac.Main");
|
||||||
|
toolsJarAvailable = true;
|
||||||
|
} catch (Exception e2) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (toolsJarAvailable) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// couldn't find compiler - try to find tools.jar
|
||||||
|
// based on java.home setting
|
||||||
|
String libToolsJar
|
||||||
|
= File.separator + "lib" + File.separator + "tools.jar";
|
||||||
|
String javaHome = System.getProperty("java.home");
|
||||||
|
File toolsJar = new File(javaHome + libToolsJar);
|
||||||
|
if (toolsJar.exists()) {
|
||||||
|
// Found in java.home as given
|
||||||
|
return toolsJar;
|
||||||
|
}
|
||||||
|
if (javaHome.toLowerCase(Locale.ENGLISH).endsWith(File.separator + "jre")) {
|
||||||
|
javaHome = javaHome.substring(
|
||||||
|
0, javaHome.length() - "/jre".length());
|
||||||
|
toolsJar = new File(javaHome + libToolsJar);
|
||||||
|
}
|
||||||
|
if (!toolsJar.exists()) {
|
||||||
|
System.out.println("Unable to locate tools.jar. "
|
||||||
|
+ "Expected to find it in " + toolsJar.getPath());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return toolsJar;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an array of URLs representing all of the jar files in the
|
||||||
|
* given location. If the location is a file, it is returned as the only
|
||||||
|
* element of the array. If the location is a directory, it is scanned for
|
||||||
|
* jar files.
|
||||||
|
*
|
||||||
|
* @param location the location to scan for Jars.
|
||||||
|
*
|
||||||
|
* @return an array of URLs for all jars in the given location.
|
||||||
|
*
|
||||||
|
* @exception MalformedURLException if the URLs for the jars cannot be
|
||||||
|
* formed.
|
||||||
|
*/
|
||||||
|
public static URL[] getLocationURLs(File location)
|
||||||
|
throws MalformedURLException {
|
||||||
|
return getLocationURLs(location, new String[]{".jar"});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an array of URLs representing all of the files of a given set of
|
||||||
|
* extensions in the given location. If the location is a file, it is
|
||||||
|
* returned as the only element of the array. If the location is a
|
||||||
|
* directory, it is scanned for matching files.
|
||||||
|
*
|
||||||
|
* @param location the location to scan for files.
|
||||||
|
* @param extensions an array of extension that are to match in the
|
||||||
|
* directory search.
|
||||||
|
*
|
||||||
|
* @return an array of URLs of matching files.
|
||||||
|
* @exception MalformedURLException if the URLs for the files cannot be
|
||||||
|
* formed.
|
||||||
|
*/
|
||||||
|
public static URL[] getLocationURLs(File location,
|
||||||
|
final String[] extensions)
|
||||||
|
throws MalformedURLException {
|
||||||
|
URL[] urls = new URL[0];
|
||||||
|
|
||||||
|
if (!location.exists()) {
|
||||||
|
return urls;
|
||||||
|
}
|
||||||
|
if (!location.isDirectory()) {
|
||||||
|
urls = new URL[1];
|
||||||
|
String path = location.getPath();
|
||||||
|
String littlePath = path.toLowerCase(Locale.ENGLISH);
|
||||||
|
for (int i = 0; i < extensions.length; ++i) {
|
||||||
|
if (littlePath.endsWith(extensions[i])) {
|
||||||
|
urls[0] = fileToURL(location);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return urls;
|
||||||
|
}
|
||||||
|
File[] matches = location.listFiles(
|
||||||
|
new FilenameFilter() {
|
||||||
|
public boolean accept(File dir, String name) {
|
||||||
|
String littleName = name.toLowerCase(Locale.ENGLISH);
|
||||||
|
for (int i = 0; i < extensions.length; ++i) {
|
||||||
|
if (littleName.endsWith(extensions[i])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
urls = new URL[matches.length];
|
||||||
|
for (int i = 0; i < matches.length; ++i) {
|
||||||
|
urls[i] = fileToURL(matches[i]);
|
||||||
|
}
|
||||||
|
return urls;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* <html>
|
||||||
|
* <head>
|
||||||
|
* <title>org.owasp.dependencycheck.org.apache.tools.ant.launch</title>
|
||||||
|
* </head>
|
||||||
|
* <body>
|
||||||
|
* This is a copy of classes within Apache Ant. The DirectoryScanner
|
||||||
|
* is needed by dependency-check. However, we did not want to make
|
||||||
|
* Ant a dependency. As such, a few files were copied and slightly
|
||||||
|
* modified to remove any references to the Ant Project class.
|
||||||
|
* </body>
|
||||||
|
* </html>
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.launch;
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* <html>
|
||||||
|
* <head>
|
||||||
|
* <title>org.owasp.dependencycheck.org.apache.tools.ant</title>
|
||||||
|
* </head>
|
||||||
|
* <body>
|
||||||
|
* This is a copy of classes within Apache Ant. The DirectoryScanner
|
||||||
|
* is needed by dependency-check. However, we did not want to make
|
||||||
|
* Ant a dependency. As such, a few files were copied and slightly
|
||||||
|
* modified to remove any references to the Ant Project class.
|
||||||
|
* </body>
|
||||||
|
* </html>
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant;
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.taskdefs.condition;
|
||||||
|
|
||||||
|
import org.owasp.dependencycheck.org.apache.tools.ant.BuildException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for conditions to use inside the <condition> task.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface Condition {
|
||||||
|
/**
|
||||||
|
* Is this condition true?
|
||||||
|
* @return true if the condition is true
|
||||||
|
* @exception BuildException if an error occurs
|
||||||
|
*/
|
||||||
|
boolean eval() throws BuildException;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,321 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.taskdefs.condition;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import org.owasp.dependencycheck.org.apache.tools.ant.BuildException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Condition that tests the OS type.
|
||||||
|
*
|
||||||
|
* @since Ant 1.4
|
||||||
|
*/
|
||||||
|
public class Os implements Condition {
|
||||||
|
private static final String OS_NAME =
|
||||||
|
System.getProperty("os.name").toLowerCase(Locale.ENGLISH);
|
||||||
|
private static final String OS_ARCH =
|
||||||
|
System.getProperty("os.arch").toLowerCase(Locale.ENGLISH);
|
||||||
|
private static final String OS_VERSION =
|
||||||
|
System.getProperty("os.version").toLowerCase(Locale.ENGLISH);
|
||||||
|
private static final String PATH_SEP =
|
||||||
|
System.getProperty("path.separator");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OS family to look for
|
||||||
|
*/
|
||||||
|
private String family;
|
||||||
|
/**
|
||||||
|
* Name of OS
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
/**
|
||||||
|
* version of OS
|
||||||
|
*/
|
||||||
|
private String version;
|
||||||
|
/**
|
||||||
|
* OS architecture
|
||||||
|
*/
|
||||||
|
private String arch;
|
||||||
|
/**
|
||||||
|
* OS family that can be tested for. {@value}
|
||||||
|
*/
|
||||||
|
public static final String FAMILY_WINDOWS = "windows";
|
||||||
|
/**
|
||||||
|
* OS family that can be tested for. {@value}
|
||||||
|
*/
|
||||||
|
public static final String FAMILY_9X = "win9x";
|
||||||
|
/**
|
||||||
|
* OS family that can be tested for. {@value}
|
||||||
|
*/
|
||||||
|
public static final String FAMILY_NT = "winnt";
|
||||||
|
/**
|
||||||
|
* OS family that can be tested for. {@value}
|
||||||
|
*/
|
||||||
|
public static final String FAMILY_OS2 = "os/2";
|
||||||
|
/**
|
||||||
|
* OS family that can be tested for. {@value}
|
||||||
|
*/
|
||||||
|
public static final String FAMILY_NETWARE = "netware";
|
||||||
|
/**
|
||||||
|
* OS family that can be tested for. {@value}
|
||||||
|
*/
|
||||||
|
public static final String FAMILY_DOS = "dos";
|
||||||
|
/**
|
||||||
|
* OS family that can be tested for. {@value}
|
||||||
|
*/
|
||||||
|
public static final String FAMILY_MAC = "mac";
|
||||||
|
/**
|
||||||
|
* OS family that can be tested for. {@value}
|
||||||
|
*/
|
||||||
|
public static final String FAMILY_TANDEM = "tandem";
|
||||||
|
/**
|
||||||
|
* OS family that can be tested for. {@value}
|
||||||
|
*/
|
||||||
|
public static final String FAMILY_UNIX = "unix";
|
||||||
|
/**
|
||||||
|
* OS family that can be tested for. {@value}
|
||||||
|
*/
|
||||||
|
public static final String FAMILY_VMS = "openvms";
|
||||||
|
/**
|
||||||
|
* OS family that can be tested for. {@value}
|
||||||
|
*/
|
||||||
|
public static final String FAMILY_ZOS = "z/os";
|
||||||
|
/** OS family that can be tested for. {@value} */
|
||||||
|
public static final String FAMILY_OS400 = "os/400";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OpenJDK is reported to call MacOS X "Darwin"
|
||||||
|
* @see https://issues.apache.org/bugzilla/show_bug.cgi?id=44889
|
||||||
|
* @see https://issues.apache.org/jira/browse/HADOOP-3318
|
||||||
|
*/
|
||||||
|
private static final String DARWIN = "darwin";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public Os() {
|
||||||
|
//default
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor that sets the family attribute
|
||||||
|
* @param family a String value
|
||||||
|
*/
|
||||||
|
public Os(String family) {
|
||||||
|
setFamily(family);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the desired OS family type
|
||||||
|
*
|
||||||
|
* @param f The OS family type desired<br>
|
||||||
|
* Possible values:<br>
|
||||||
|
* <ul>
|
||||||
|
* <li>dos</li>
|
||||||
|
* <li>mac</li>
|
||||||
|
* <li>netware</li>
|
||||||
|
* <li>os/2</li>
|
||||||
|
* <li>tandem</li>
|
||||||
|
* <li>unix</li>
|
||||||
|
* <li>windows</li>
|
||||||
|
* <li>win9x</li>
|
||||||
|
* <li>z/os</li>
|
||||||
|
* <li>os/400</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public void setFamily(String f) {
|
||||||
|
family = f.toLowerCase(Locale.ENGLISH);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the desired OS name
|
||||||
|
*
|
||||||
|
* @param name The OS name
|
||||||
|
*/
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name.toLowerCase(Locale.ENGLISH);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the desired OS architecture
|
||||||
|
*
|
||||||
|
* @param arch The OS architecture
|
||||||
|
*/
|
||||||
|
public void setArch(String arch) {
|
||||||
|
this.arch = arch.toLowerCase(Locale.ENGLISH);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the desired OS version
|
||||||
|
*
|
||||||
|
* @param version The OS version
|
||||||
|
*/
|
||||||
|
public void setVersion(String version) {
|
||||||
|
this.version = version.toLowerCase(Locale.ENGLISH);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the OS on which Ant is executing matches the type of
|
||||||
|
* that set in setFamily.
|
||||||
|
* @return true if the os matches.
|
||||||
|
* @throws BuildException if there is an error.
|
||||||
|
* @see Os#setFamily(String)
|
||||||
|
*/
|
||||||
|
public boolean eval() throws BuildException {
|
||||||
|
return isOs(family, name, arch, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the OS on which Ant is executing matches the
|
||||||
|
* given OS family.
|
||||||
|
* @param family the family to check for
|
||||||
|
* @return true if the OS matches
|
||||||
|
* @since 1.5
|
||||||
|
*/
|
||||||
|
public static boolean isFamily(String family) {
|
||||||
|
return isOs(family, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the OS on which Ant is executing matches the
|
||||||
|
* given OS name.
|
||||||
|
*
|
||||||
|
* @param name the OS name to check for
|
||||||
|
* @return true if the OS matches
|
||||||
|
* @since 1.7
|
||||||
|
*/
|
||||||
|
public static boolean isName(String name) {
|
||||||
|
return isOs(null, name, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the OS on which Ant is executing matches the
|
||||||
|
* given OS architecture.
|
||||||
|
*
|
||||||
|
* @param arch the OS architecture to check for
|
||||||
|
* @return true if the OS matches
|
||||||
|
* @since 1.7
|
||||||
|
*/
|
||||||
|
public static boolean isArch(String arch) {
|
||||||
|
return isOs(null, null, arch, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the OS on which Ant is executing matches the
|
||||||
|
* given OS version.
|
||||||
|
*
|
||||||
|
* @param version the OS version to check for
|
||||||
|
* @return true if the OS matches
|
||||||
|
* @since 1.7
|
||||||
|
*/
|
||||||
|
public static boolean isVersion(String version) {
|
||||||
|
return isOs(null, null, null, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the OS on which Ant is executing matches the
|
||||||
|
* given OS family, name, architecture and version
|
||||||
|
*
|
||||||
|
* @param family The OS family
|
||||||
|
* @param name The OS name
|
||||||
|
* @param arch The OS architecture
|
||||||
|
* @param version The OS version
|
||||||
|
* @return true if the OS matches
|
||||||
|
* @since 1.7
|
||||||
|
*/
|
||||||
|
public static boolean isOs(String family, String name, String arch,
|
||||||
|
String version) {
|
||||||
|
boolean retValue = false;
|
||||||
|
|
||||||
|
if (family != null || name != null || arch != null
|
||||||
|
|| version != null) {
|
||||||
|
|
||||||
|
boolean isFamily = true;
|
||||||
|
boolean isName = true;
|
||||||
|
boolean isArch = true;
|
||||||
|
boolean isVersion = true;
|
||||||
|
|
||||||
|
if (family != null) {
|
||||||
|
|
||||||
|
//windows probing logic relies on the word 'windows' in
|
||||||
|
//the OS
|
||||||
|
boolean isWindows = OS_NAME.indexOf(FAMILY_WINDOWS) > -1;
|
||||||
|
boolean is9x = false;
|
||||||
|
boolean isNT = false;
|
||||||
|
if (isWindows) {
|
||||||
|
//there are only four 9x platforms that we look for
|
||||||
|
is9x = (OS_NAME.indexOf("95") >= 0
|
||||||
|
|| OS_NAME.indexOf("98") >= 0
|
||||||
|
|| OS_NAME.indexOf("me") >= 0
|
||||||
|
//wince isn't really 9x, but crippled enough to
|
||||||
|
//be a muchness. Ant doesnt run on CE, anyway.
|
||||||
|
|| OS_NAME.indexOf("ce") >= 0);
|
||||||
|
isNT = !is9x;
|
||||||
|
}
|
||||||
|
if (family.equals(FAMILY_WINDOWS)) {
|
||||||
|
isFamily = isWindows;
|
||||||
|
} else if (family.equals(FAMILY_9X)) {
|
||||||
|
isFamily = isWindows && is9x;
|
||||||
|
} else if (family.equals(FAMILY_NT)) {
|
||||||
|
isFamily = isWindows && isNT;
|
||||||
|
} else if (family.equals(FAMILY_OS2)) {
|
||||||
|
isFamily = OS_NAME.indexOf(FAMILY_OS2) > -1;
|
||||||
|
} else if (family.equals(FAMILY_NETWARE)) {
|
||||||
|
isFamily = OS_NAME.indexOf(FAMILY_NETWARE) > -1;
|
||||||
|
} else if (family.equals(FAMILY_DOS)) {
|
||||||
|
isFamily = PATH_SEP.equals(";") && !isFamily(FAMILY_NETWARE);
|
||||||
|
} else if (family.equals(FAMILY_MAC)) {
|
||||||
|
isFamily = OS_NAME.indexOf(FAMILY_MAC) > -1
|
||||||
|
|| OS_NAME.indexOf(DARWIN) > -1;
|
||||||
|
} else if (family.equals(FAMILY_TANDEM)) {
|
||||||
|
isFamily = OS_NAME.indexOf("nonstop_kernel") > -1;
|
||||||
|
} else if (family.equals(FAMILY_UNIX)) {
|
||||||
|
isFamily = PATH_SEP.equals(":")
|
||||||
|
&& !isFamily(FAMILY_VMS)
|
||||||
|
&& (!isFamily(FAMILY_MAC) || OS_NAME.endsWith("x")
|
||||||
|
|| OS_NAME.indexOf(DARWIN) > -1);
|
||||||
|
} else if (family.equals(FAMILY_ZOS)) {
|
||||||
|
isFamily = OS_NAME.indexOf(FAMILY_ZOS) > -1
|
||||||
|
|| OS_NAME.indexOf("os/390") > -1;
|
||||||
|
} else if (family.equals(FAMILY_OS400)) {
|
||||||
|
isFamily = OS_NAME.indexOf(FAMILY_OS400) > -1;
|
||||||
|
} else if (family.equals(FAMILY_VMS)) {
|
||||||
|
isFamily = OS_NAME.indexOf(FAMILY_VMS) > -1;
|
||||||
|
} else {
|
||||||
|
throw new BuildException(
|
||||||
|
"Don\'t know how to detect os family \""
|
||||||
|
+ family + "\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (name != null) {
|
||||||
|
isName = name.equals(OS_NAME);
|
||||||
|
}
|
||||||
|
if (arch != null) {
|
||||||
|
isArch = arch.equals(OS_ARCH);
|
||||||
|
}
|
||||||
|
if (version != null) {
|
||||||
|
isVersion = version.equals(OS_VERSION);
|
||||||
|
}
|
||||||
|
retValue = isFamily && isName && isArch && isVersion;
|
||||||
|
}
|
||||||
|
return retValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* <html>
|
||||||
|
* <head>
|
||||||
|
* <title>org.owasp.dependencycheck.org.apache.tools.ant.taskdefs.condition</title>
|
||||||
|
* </head>
|
||||||
|
* <body>
|
||||||
|
* This is a copy of classes within Apache Ant. The DirectoryScanner
|
||||||
|
* is needed by dependency-check. However, we did not want to make
|
||||||
|
* Ant a dependency. As such, a few files were copied and slightly
|
||||||
|
* modified to remove any references to the Ant Project class.
|
||||||
|
* </body>
|
||||||
|
* </html>
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.taskdefs.condition;
|
||||||
@@ -0,0 +1,353 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.types;
|
||||||
|
|
||||||
|
import org.owasp.dependencycheck.org.apache.tools.ant.BuildException;
|
||||||
|
import org.owasp.dependencycheck.org.apache.tools.ant.ProjectComponent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for those classes that can appear inside the build file as stand alone data types.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* This class handles the common description attribute and provides a default implementation for reference handling and
|
||||||
|
* checking for circular references that is appropriate for types that can not be nested inside elements of the same
|
||||||
|
* type (i.e. <patternset> but not <path>).</p>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class DataType extends ProjectComponent implements Cloneable {
|
||||||
|
// CheckStyle:VisibilityModifier OFF
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value to the refid attribute.
|
||||||
|
*
|
||||||
|
* @deprecated since 1.7. The user should not be directly referencing variable. Please use {@link #getRefid}
|
||||||
|
* instead.
|
||||||
|
*/
|
||||||
|
protected Reference ref;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Are we sure we don't hold circular references?
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Subclasses are responsible for setting this value to false if we'd need to investigate this condition (usually
|
||||||
|
* because a child element has been added that is a subclass of DataType).</p>
|
||||||
|
*
|
||||||
|
* @deprecated since 1.7. The user should not be directly referencing variable. Please use {@link #setChecked} or
|
||||||
|
* {@link #isChecked} instead.
|
||||||
|
*/
|
||||||
|
protected boolean checked = true;
|
||||||
|
// CheckStyle:VisibilityModifier ON
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Has the refid attribute of this element been set?
|
||||||
|
*
|
||||||
|
* @return true if the refid attribute has been set
|
||||||
|
*/
|
||||||
|
public boolean isReference() {
|
||||||
|
return ref != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of the refid attribute.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Subclasses may need to check whether any other attributes have been set as well or child elements have been
|
||||||
|
* created and thus override this method. if they do the must call <code>super.setRefid</code>.</p>
|
||||||
|
*
|
||||||
|
* @param ref the reference to use
|
||||||
|
*/
|
||||||
|
public void setRefid(final Reference ref) {
|
||||||
|
this.ref = ref;
|
||||||
|
checked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Gets as descriptive as possible a name used for this datatype instance.
|
||||||
|
// *
|
||||||
|
// * @return <code>String</code> name.
|
||||||
|
// */
|
||||||
|
// protected String getDataTypeName() {
|
||||||
|
// return ComponentHelper.getElementName(getProject(), this, true);
|
||||||
|
// }
|
||||||
|
// /**
|
||||||
|
// * Convenience method.
|
||||||
|
// * @since Ant 1.7
|
||||||
|
// */
|
||||||
|
// protected void dieOnCircularReference() {
|
||||||
|
// dieOnCircularReference(getProject());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Convenience method.
|
||||||
|
// * @param p the Ant Project instance against which to resolve references.
|
||||||
|
// * @since Ant 1.7
|
||||||
|
// */
|
||||||
|
// protected void dieOnCircularReference(Project p) {
|
||||||
|
// if (checked || !isReference()) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// dieOnCircularReference(new IdentityStack<Object>(this), p);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Check to see whether any DataType we hold references to is
|
||||||
|
// * included in the Stack (which holds all DataType instances that
|
||||||
|
// * directly or indirectly reference this instance, including this
|
||||||
|
// * instance itself).
|
||||||
|
// *
|
||||||
|
// * <p>If one is included, throw a BuildException created by {@link
|
||||||
|
// * #circularReference circularReference}.</p>
|
||||||
|
// *
|
||||||
|
// * <p>This implementation is appropriate only for a DataType that
|
||||||
|
// * cannot hold other DataTypes as children.</p>
|
||||||
|
// *
|
||||||
|
// * <p>The general contract of this method is that it shouldn't do
|
||||||
|
// * anything if {@link #checked <code>checked</code>} is true and
|
||||||
|
// * set it to true on exit.</p>
|
||||||
|
// * @param stack the stack of references to check.
|
||||||
|
// * @param project the project to use to dereference the references.
|
||||||
|
// * @throws BuildException on error.
|
||||||
|
// */
|
||||||
|
// protected void dieOnCircularReference(final Stack<Object> stack,
|
||||||
|
// final Project project)
|
||||||
|
// throws BuildException {
|
||||||
|
//
|
||||||
|
// if (checked || !isReference()) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// Object o = ref.getReferencedObject(project);
|
||||||
|
//
|
||||||
|
// if (o instanceof DataType) {
|
||||||
|
// IdentityStack<Object> id = IdentityStack.getInstance(stack);
|
||||||
|
//
|
||||||
|
// if (id.contains(o)) {
|
||||||
|
// throw circularReference();
|
||||||
|
// } else {
|
||||||
|
// id.push(o);
|
||||||
|
// ((DataType) o).dieOnCircularReference(id, project);
|
||||||
|
// id.pop();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// checked = true;
|
||||||
|
// }
|
||||||
|
// /**
|
||||||
|
// * Allow DataTypes outside org.apache.tools.ant.types to indirectly call dieOnCircularReference on nested DataTypes.
|
||||||
|
// *
|
||||||
|
// * @param dt the DataType to check.
|
||||||
|
// * @param stk the stack of references to check.
|
||||||
|
// * @param p the project to use to dereference the references.
|
||||||
|
// * @throws BuildException on error.
|
||||||
|
// * @since Ant 1.7
|
||||||
|
// */
|
||||||
|
// public static void invokeCircularReferenceCheck(DataType dt, Stack<Object> stk,
|
||||||
|
// Project p) {
|
||||||
|
// dt.dieOnCircularReference(stk, p);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Allow DataTypes outside org.apache.tools.ant.types to indirectly call dieOnCircularReference on nested DataTypes.
|
||||||
|
// *
|
||||||
|
// * <p>
|
||||||
|
// * Pushes dt on the stack, runs dieOnCircularReference and pops it again.</p>
|
||||||
|
// *
|
||||||
|
// * @param dt the DataType to check.
|
||||||
|
// * @param stk the stack of references to check.
|
||||||
|
// * @param p the project to use to dereference the references.
|
||||||
|
// * @throws BuildException on error.
|
||||||
|
// * @since Ant 1.8.0
|
||||||
|
// */
|
||||||
|
// public static void pushAndInvokeCircularReferenceCheck(DataType dt,
|
||||||
|
// Stack<Object> stk,
|
||||||
|
// Project p) {
|
||||||
|
// stk.push(dt);
|
||||||
|
// dt.dieOnCircularReference(stk, p);
|
||||||
|
// stk.pop();
|
||||||
|
// }
|
||||||
|
// /**
|
||||||
|
// * Performs the check for circular references and returns the referenced object.
|
||||||
|
// *
|
||||||
|
// * @return the dereferenced object.
|
||||||
|
// * @throws BuildException if the reference is invalid (circular ref, wrong class, etc).
|
||||||
|
// * @since Ant 1.7
|
||||||
|
// */
|
||||||
|
// protected Object getCheckedRef() {
|
||||||
|
// return getCheckedRef(getProject());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Performs the check for circular references and returns the referenced object.
|
||||||
|
// *
|
||||||
|
// * @param p the Ant Project instance against which to resolve references.
|
||||||
|
// * @return the dereferenced object.
|
||||||
|
// * @throws BuildException if the reference is invalid (circular ref, wrong class, etc).
|
||||||
|
// * @since Ant 1.7
|
||||||
|
// */
|
||||||
|
// protected Object getCheckedRef(Project p) {
|
||||||
|
// return getCheckedRef(getClass(), getDataTypeName(), p);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Performs the check for circular references and returns the referenced object.
|
||||||
|
// *
|
||||||
|
// * @param requiredClass the class that this reference should be a subclass of.
|
||||||
|
// * @param dataTypeName the name of the datatype that the reference should be (error message use only).
|
||||||
|
// * @return the dereferenced object.
|
||||||
|
// * @throws BuildException if the reference is invalid (circular ref, wrong class, etc).
|
||||||
|
// */
|
||||||
|
// protected <T> T getCheckedRef(final Class<T> requiredClass,
|
||||||
|
// final String dataTypeName) {
|
||||||
|
// return getCheckedRef(requiredClass, dataTypeName, getProject());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Performs the check for circular references and returns the referenced object. This version allows the fallback
|
||||||
|
// * Project instance to be specified.
|
||||||
|
// *
|
||||||
|
// * @param requiredClass the class that this reference should be a subclass of.
|
||||||
|
// * @param dataTypeName the name of the datatype that the reference should be (error message use only).
|
||||||
|
// * @param project the fallback Project instance for dereferencing.
|
||||||
|
// * @return the dereferenced object.
|
||||||
|
// * @throws BuildException if the reference is invalid (circular ref, wrong class, etc), or if <code>project</code>
|
||||||
|
// * is <code>null</code>.
|
||||||
|
// * @since Ant 1.7
|
||||||
|
// */
|
||||||
|
// protected <T> T getCheckedRef(final Class<T> requiredClass,
|
||||||
|
// final String dataTypeName, final Project project) {
|
||||||
|
// if (project == null) {
|
||||||
|
// throw new BuildException("No Project specified");
|
||||||
|
// }
|
||||||
|
// dieOnCircularReference(project);
|
||||||
|
// Object o = ref.getReferencedObject(project);
|
||||||
|
// if (!(requiredClass.isAssignableFrom(o.getClass()))) {
|
||||||
|
// log("Class " + o.getClass() + " is not a subclass of " + requiredClass,
|
||||||
|
// Project.MSG_VERBOSE);
|
||||||
|
// String msg = ref.getRefId() + " doesn\'t denote a " + dataTypeName;
|
||||||
|
// throw new BuildException(msg);
|
||||||
|
// }
|
||||||
|
// @SuppressWarnings("unchecked")
|
||||||
|
// final T result = (T) o;
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
/**
|
||||||
|
* Creates an exception that indicates that refid has to be the only attribute if it is set.
|
||||||
|
*
|
||||||
|
* @return the exception to throw
|
||||||
|
*/
|
||||||
|
protected BuildException tooManyAttributes() {
|
||||||
|
return new BuildException("You must not specify more than one "
|
||||||
|
+ "attribute when using refid");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an exception that indicates that this XML element must not have child elements if the refid attribute is
|
||||||
|
* set.
|
||||||
|
*
|
||||||
|
* @return the exception to throw
|
||||||
|
*/
|
||||||
|
protected BuildException noChildrenAllowed() {
|
||||||
|
return new BuildException("You must not specify nested elements "
|
||||||
|
+ "when using refid");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an exception that indicates the user has generated a loop of data types referencing each other.
|
||||||
|
*
|
||||||
|
* @return the exception to throw
|
||||||
|
*/
|
||||||
|
protected BuildException circularReference() {
|
||||||
|
return new BuildException("This data type contains a circular "
|
||||||
|
+ "reference.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The flag that is used to indicate that circular references have been checked.
|
||||||
|
*
|
||||||
|
* @return true if circular references have been checked
|
||||||
|
*/
|
||||||
|
protected boolean isChecked() {
|
||||||
|
return checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the flag that is used to indicate that circular references have been checked.
|
||||||
|
*
|
||||||
|
* @param checked if true, if circular references have been checked
|
||||||
|
*/
|
||||||
|
protected void setChecked(final boolean checked) {
|
||||||
|
this.checked = checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the reference set on this object
|
||||||
|
*
|
||||||
|
* @return the reference or null
|
||||||
|
*/
|
||||||
|
public Reference getRefid() {
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check that it is ok to set attributes, i.e that no reference is defined
|
||||||
|
*
|
||||||
|
* @since Ant 1.6
|
||||||
|
* @throws BuildException if not allowed
|
||||||
|
*/
|
||||||
|
protected void checkAttributesAllowed() {
|
||||||
|
if (isReference()) {
|
||||||
|
throw tooManyAttributes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check that it is ok to add children, i.e that no reference is defined
|
||||||
|
*
|
||||||
|
* @since Ant 1.6
|
||||||
|
* @throws BuildException if not allowed
|
||||||
|
*/
|
||||||
|
protected void checkChildrenAllowed() {
|
||||||
|
if (isReference()) {
|
||||||
|
throw noChildrenAllowed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic DataType toString().
|
||||||
|
*
|
||||||
|
* @return this DataType formatted as a String.
|
||||||
|
*/
|
||||||
|
public String toString() {
|
||||||
|
String d = getDescription();
|
||||||
|
//return d == null ? getDataTypeName() : getDataTypeName() + " " + d;
|
||||||
|
return d == null ? "DataType" : d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since Ant 1.7
|
||||||
|
* @return a shallow copy of this DataType.
|
||||||
|
* @throws CloneNotSupportedException if there is a problem.
|
||||||
|
*/
|
||||||
|
public Object clone() throws CloneNotSupportedException {
|
||||||
|
DataType dt = (DataType) super.clone();
|
||||||
|
dt.setDescription(getDescription());
|
||||||
|
if (getRefid() != null) {
|
||||||
|
dt.setRefid(getRefid());
|
||||||
|
}
|
||||||
|
dt.setChecked(isChecked());
|
||||||
|
return dt;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.types;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to hold a reference to another object in the project.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Reference {
|
||||||
|
|
||||||
|
private String refid;
|
||||||
|
//private Project project;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a reference.
|
||||||
|
*
|
||||||
|
* @deprecated since 1.7. Please use {@link Reference#Reference(Project,String)} instead.
|
||||||
|
*/
|
||||||
|
public Reference() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a reference to a named ID.
|
||||||
|
*
|
||||||
|
* @param id the name of this reference
|
||||||
|
* @deprecated since 1.7. Please use {@link Reference#Reference(Project,String)} instead.
|
||||||
|
*/
|
||||||
|
public Reference(String id) {
|
||||||
|
setRefId(id);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Create a reference to a named ID in a particular project.
|
||||||
|
// * @param p the project this reference is associated with
|
||||||
|
// * @param id the name of this reference
|
||||||
|
// * @since Ant 1.6.3
|
||||||
|
// */
|
||||||
|
// public Reference(Project p, String id) {
|
||||||
|
// setRefId(id);
|
||||||
|
// setProject(p);
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the reference id. Should not normally be necessary; use {@link Reference#Reference(Project, String)}.
|
||||||
|
*
|
||||||
|
* @param id the reference id to use
|
||||||
|
*/
|
||||||
|
public void setRefId(String id) {
|
||||||
|
refid = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the reference id of this reference.
|
||||||
|
*
|
||||||
|
* @return the reference id
|
||||||
|
*/
|
||||||
|
public String getRefId() {
|
||||||
|
return refid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Set the associated project. Should not normally be necessary;
|
||||||
|
// * use {@link Reference#Reference(Project,String)}.
|
||||||
|
// * @param p the project to use
|
||||||
|
// * @since Ant 1.6.3
|
||||||
|
// */
|
||||||
|
// public void setProject(Project p) {
|
||||||
|
// this.project = p;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Get the associated project, if any; may be null.
|
||||||
|
// * @return the associated project
|
||||||
|
// * @since Ant 1.6.3
|
||||||
|
// */
|
||||||
|
// public Project getProject() {
|
||||||
|
// return project;
|
||||||
|
// }
|
||||||
|
// /**
|
||||||
|
// * Resolve the reference, using the associated project if
|
||||||
|
// * it set, otherwise use the passed in project.
|
||||||
|
// * @param fallback the fallback project to use if the project attribute of
|
||||||
|
// * reference is not set.
|
||||||
|
// * @return the dereferenced object.
|
||||||
|
// * @throws BuildException if the reference cannot be dereferenced.
|
||||||
|
// */
|
||||||
|
// public Object getReferencedObject(Project fallback) throws BuildException {
|
||||||
|
// if (refid == null) {
|
||||||
|
// throw new BuildException("No reference specified");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Object o = project == null ? fallback.getReference(refid) : project.getReference(refid);
|
||||||
|
// if (o == null) {
|
||||||
|
// throw new BuildException("Reference " + refid + " not found.");
|
||||||
|
// }
|
||||||
|
// return o;
|
||||||
|
// }
|
||||||
|
// /**
|
||||||
|
// * Resolve the reference, looking in the associated project.
|
||||||
|
// * @see Project#getReference
|
||||||
|
// * @return the dereferenced object.
|
||||||
|
// * @throws BuildException if the project is null or the reference cannot be dereferenced
|
||||||
|
// * @since Ant 1.6.3
|
||||||
|
// */
|
||||||
|
// public Object getReferencedObject() throws BuildException {
|
||||||
|
// if (project == null) {
|
||||||
|
// throw new BuildException("No project set on reference to " + refid);
|
||||||
|
// }
|
||||||
|
// return getReferencedObject(project);
|
||||||
|
// }
|
||||||
|
}
|
||||||
@@ -0,0 +1,462 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.types;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import org.owasp.dependencycheck.org.apache.tools.ant.types.resources.FileProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes a "File-like" resource (File, ZipEntry, etc.).
|
||||||
|
*
|
||||||
|
* This class is meant to be used by classes needing to record path and date/time information about a file, a zip entry
|
||||||
|
* or some similar resource (URL, archive in a version control repository, ...).
|
||||||
|
*
|
||||||
|
* @since Ant 1.5.2
|
||||||
|
* @see org.apache.tools.ant.types.resources.Touchable
|
||||||
|
*/
|
||||||
|
public class Resource extends DataType implements Comparable<Resource>, ResourceCollection {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constant unknown size
|
||||||
|
*/
|
||||||
|
public static final long UNKNOWN_SIZE = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constant unknown datetime for getLastModified
|
||||||
|
*/
|
||||||
|
public static final long UNKNOWN_DATETIME = 0L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic number
|
||||||
|
*/
|
||||||
|
protected static final int MAGIC = getMagicNumber("Resource".getBytes());
|
||||||
|
|
||||||
|
private static final int NULL_NAME = getMagicNumber("null name".getBytes());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a "magic number" for use in hashCode calculations.
|
||||||
|
*
|
||||||
|
* @param seed byte[] to seed with.
|
||||||
|
* @return a magic number as int.
|
||||||
|
*/
|
||||||
|
protected static int getMagicNumber(byte[] seed) {
|
||||||
|
return new BigInteger(seed).intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String name = null;
|
||||||
|
private Boolean exists = null;
|
||||||
|
private Long lastmodified = null;
|
||||||
|
private Boolean directory = null;
|
||||||
|
private Long size = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor.
|
||||||
|
*/
|
||||||
|
public Resource() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only sets the name.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* This is a dummy, used for not existing resources.</p>
|
||||||
|
*
|
||||||
|
* @param name relative path of the resource. Expects "/" to be used as the directory separator.
|
||||||
|
*/
|
||||||
|
public Resource(String name) {
|
||||||
|
this(name, false, 0, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the name, lastmodified flag, and exists flag.
|
||||||
|
*
|
||||||
|
* @param name relative path of the resource. Expects "/" to be used as the directory separator.
|
||||||
|
* @param exists if true, this resource exists.
|
||||||
|
* @param lastmodified the last modification time of this resource.
|
||||||
|
*/
|
||||||
|
public Resource(String name, boolean exists, long lastmodified) {
|
||||||
|
this(name, exists, lastmodified, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the name, lastmodified flag, exists flag, and directory flag.
|
||||||
|
*
|
||||||
|
* @param name relative path of the resource. Expects "/" to be used as the directory separator.
|
||||||
|
* @param exists if true the resource exists
|
||||||
|
* @param lastmodified the last modification time of the resource
|
||||||
|
* @param directory if true, this resource is a directory
|
||||||
|
*/
|
||||||
|
public Resource(String name, boolean exists, long lastmodified, boolean directory) {
|
||||||
|
this(name, exists, lastmodified, directory, UNKNOWN_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the name, lastmodified flag, exists flag, directory flag, and size.
|
||||||
|
*
|
||||||
|
* @param name relative path of the resource. Expects "/" to be used as the directory separator.
|
||||||
|
* @param exists if true the resource exists
|
||||||
|
* @param lastmodified the last modification time of the resource
|
||||||
|
* @param directory if true, this resource is a directory
|
||||||
|
* @param size the size of this resource.
|
||||||
|
*/
|
||||||
|
public Resource(String name, boolean exists, long lastmodified, boolean directory, long size) {
|
||||||
|
this.name = name;
|
||||||
|
setName(name);
|
||||||
|
setExists(exists);
|
||||||
|
setLastModified(lastmodified);
|
||||||
|
setDirectory(directory);
|
||||||
|
setSize(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name attribute will contain the path of a file relative to the root directory of its fileset or the recorded path
|
||||||
|
* of a zip entry.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* example for a file with fullpath /var/opt/adm/resource.txt in a file set with root dir /var/opt it will be
|
||||||
|
* adm/resource.txt.</p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* "/" will be used as the directory separator.</p>
|
||||||
|
*
|
||||||
|
* @return the name of this resource.
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
//return isReference() ? ((Resource) getCheckedRef()).getName() : name;
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the name of this Resource.
|
||||||
|
*
|
||||||
|
* @param name relative path of the resource. Expects "/" to be used as the directory separator.
|
||||||
|
*/
|
||||||
|
public void setName(String name) {
|
||||||
|
checkAttributesAllowed();
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The exists attribute tells whether a resource exists.
|
||||||
|
*
|
||||||
|
* @return true if this resource exists.
|
||||||
|
*/
|
||||||
|
public boolean isExists() {
|
||||||
|
// if (isReference()) {
|
||||||
|
// return ((Resource) getCheckedRef()).isExists();
|
||||||
|
// }
|
||||||
|
//default true:
|
||||||
|
return exists == null || exists.booleanValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the exists attribute.
|
||||||
|
*
|
||||||
|
* @param exists if true, this resource exists.
|
||||||
|
*/
|
||||||
|
public void setExists(boolean exists) {
|
||||||
|
checkAttributesAllowed();
|
||||||
|
this.exists = exists ? Boolean.TRUE : Boolean.FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells the modification time in milliseconds since 01.01.1970 (the "epoch").
|
||||||
|
*
|
||||||
|
* @return the modification time, if that is meaningful (e.g. for a file resource which exists); 0 if the resource
|
||||||
|
* does not exist, to mirror the behavior of {@link java.io.File#lastModified}; or 0 if the notion of modification
|
||||||
|
* time is meaningless for this class of resource (e.g. an inline string)
|
||||||
|
*/
|
||||||
|
public long getLastModified() {
|
||||||
|
// if (isReference()) {
|
||||||
|
// return ((Resource) getCheckedRef()).getLastModified();
|
||||||
|
// }
|
||||||
|
if (!isExists() || lastmodified == null) {
|
||||||
|
return UNKNOWN_DATETIME;
|
||||||
|
}
|
||||||
|
long result = lastmodified.longValue();
|
||||||
|
return result < UNKNOWN_DATETIME ? UNKNOWN_DATETIME : result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the last modification attribute.
|
||||||
|
*
|
||||||
|
* @param lastmodified the modification time in milliseconds since 01.01.1970.
|
||||||
|
*/
|
||||||
|
public void setLastModified(long lastmodified) {
|
||||||
|
checkAttributesAllowed();
|
||||||
|
this.lastmodified = new Long(lastmodified);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells if the resource is a directory.
|
||||||
|
*
|
||||||
|
* @return boolean flag indicating if the resource is a directory.
|
||||||
|
*/
|
||||||
|
public boolean isDirectory() {
|
||||||
|
// if (isReference()) {
|
||||||
|
// return ((Resource) getCheckedRef()).isDirectory();
|
||||||
|
// }
|
||||||
|
//default false:
|
||||||
|
return directory != null && directory.booleanValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the directory attribute.
|
||||||
|
*
|
||||||
|
* @param directory if true, this resource is a directory.
|
||||||
|
*/
|
||||||
|
public void setDirectory(boolean directory) {
|
||||||
|
checkAttributesAllowed();
|
||||||
|
this.directory = directory ? Boolean.TRUE : Boolean.FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the size of this Resource.
|
||||||
|
*
|
||||||
|
* @param size the size, as a long.
|
||||||
|
* @since Ant 1.6.3
|
||||||
|
*/
|
||||||
|
public void setSize(long size) {
|
||||||
|
checkAttributesAllowed();
|
||||||
|
this.size = new Long(size > UNKNOWN_SIZE ? size : UNKNOWN_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the size of this Resource.
|
||||||
|
*
|
||||||
|
* @return the size, as a long, 0 if the Resource does not exist (for compatibility with java.io.File), or
|
||||||
|
* UNKNOWN_SIZE if not known.
|
||||||
|
* @since Ant 1.6.3
|
||||||
|
*/
|
||||||
|
public long getSize() {
|
||||||
|
// if (isReference()) {
|
||||||
|
// return ((Resource) getCheckedRef()).getSize();
|
||||||
|
// }
|
||||||
|
return isExists()
|
||||||
|
? (size != null ? size.longValue() : UNKNOWN_SIZE)
|
||||||
|
: 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clone this Resource.
|
||||||
|
*
|
||||||
|
* @return copy of this.
|
||||||
|
*/
|
||||||
|
public Object clone() {
|
||||||
|
try {
|
||||||
|
return super.clone();
|
||||||
|
} catch (CloneNotSupportedException e) {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"CloneNotSupportedException for a Resource caught. "
|
||||||
|
+ "Derived classes must support cloning.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delegates to a comparison of names.
|
||||||
|
*
|
||||||
|
* @param other the object to compare to.
|
||||||
|
* @return a negative integer, zero, or a positive integer as this Resource is less than, equal to, or greater than
|
||||||
|
* the specified Resource.
|
||||||
|
* @since Ant 1.6
|
||||||
|
*/
|
||||||
|
public int compareTo(Resource other) {
|
||||||
|
// if (isReference()) {
|
||||||
|
// return ((Resource) getCheckedRef()).compareTo(other);
|
||||||
|
// }
|
||||||
|
return toString().compareTo(other.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implement basic Resource equality.
|
||||||
|
*
|
||||||
|
* @param other the object to check against.
|
||||||
|
* @return true if the specified Object is equal to this Resource.
|
||||||
|
* @since Ant 1.7
|
||||||
|
*/
|
||||||
|
public boolean equals(Object other) {
|
||||||
|
// if (isReference()) {
|
||||||
|
// return getCheckedRef().equals(other);
|
||||||
|
// }
|
||||||
|
return other != null && other.getClass().equals(getClass())
|
||||||
|
&& compareTo((Resource) other) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the hash code for this Resource.
|
||||||
|
*
|
||||||
|
* @return hash code as int.
|
||||||
|
* @since Ant 1.7
|
||||||
|
*/
|
||||||
|
public int hashCode() {
|
||||||
|
// if (isReference()) {
|
||||||
|
// return getCheckedRef().hashCode();
|
||||||
|
// }
|
||||||
|
String name = getName();
|
||||||
|
return MAGIC * (name == null ? NULL_NAME : name.hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an InputStream for the Resource.
|
||||||
|
*
|
||||||
|
* @return an InputStream containing this Resource's content.
|
||||||
|
* @throws IOException if unable to provide the content of this Resource as a stream.
|
||||||
|
* @throws UnsupportedOperationException if InputStreams are not supported for this Resource type.
|
||||||
|
* @since Ant 1.7
|
||||||
|
*/
|
||||||
|
public InputStream getInputStream() throws IOException {
|
||||||
|
// if (isReference()) {
|
||||||
|
// return ((Resource) getCheckedRef()).getInputStream();
|
||||||
|
// }
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an OutputStream for the Resource.
|
||||||
|
*
|
||||||
|
* @return an OutputStream to which content can be written.
|
||||||
|
* @throws IOException if unable to provide the content of this Resource as a stream.
|
||||||
|
* @throws UnsupportedOperationException if OutputStreams are not supported for this Resource type.
|
||||||
|
* @since Ant 1.7
|
||||||
|
*/
|
||||||
|
public OutputStream getOutputStream() throws IOException {
|
||||||
|
// if (isReference()) {
|
||||||
|
// return ((Resource) getCheckedRef()).getOutputStream();
|
||||||
|
// }
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fulfill the ResourceCollection contract.
|
||||||
|
*
|
||||||
|
* @return an Iterator of Resources.
|
||||||
|
* @since Ant 1.7
|
||||||
|
*/
|
||||||
|
public Iterator<Resource> iterator() {
|
||||||
|
//return isReference() ? ((Resource) getCheckedRef()).iterator()
|
||||||
|
// : new Iterator<Resource>() {
|
||||||
|
return new Iterator<Resource>() {
|
||||||
|
private boolean done = false;
|
||||||
|
|
||||||
|
public boolean hasNext() {
|
||||||
|
return !done;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Resource next() {
|
||||||
|
if (done) {
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
}
|
||||||
|
done = true;
|
||||||
|
return Resource.this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fulfill the ResourceCollection contract.
|
||||||
|
*
|
||||||
|
* @return the size of this ResourceCollection.
|
||||||
|
* @since Ant 1.7
|
||||||
|
*/
|
||||||
|
public int size() {
|
||||||
|
//return isReference() ? ((Resource) getCheckedRef()).size() : 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fulfill the ResourceCollection contract.
|
||||||
|
*
|
||||||
|
* @return whether this Resource is a FileProvider.
|
||||||
|
* @since Ant 1.7
|
||||||
|
*/
|
||||||
|
public boolean isFilesystemOnly() {
|
||||||
|
// return (isReference() && ((Resource) getCheckedRef()).isFilesystemOnly())
|
||||||
|
// || this.as(FileProvider.class) != null;
|
||||||
|
return this.as(FileProvider.class) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the string representation of this Resource.
|
||||||
|
*
|
||||||
|
* @return this Resource formatted as a String.
|
||||||
|
* @since Ant 1.7
|
||||||
|
*/
|
||||||
|
public String toString() {
|
||||||
|
// if (isReference()) {
|
||||||
|
// return getCheckedRef().toString();
|
||||||
|
// }
|
||||||
|
String n = getName();
|
||||||
|
return n == null ? "(anonymous)" : n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a long String representation of this Resource. This typically should be the value of <code>toString()</code>
|
||||||
|
* prefixed by a type description.
|
||||||
|
*
|
||||||
|
* @return this Resource formatted as a long String.
|
||||||
|
* @since Ant 1.7
|
||||||
|
*/
|
||||||
|
public final String toLongString() {
|
||||||
|
// return isReference() ? ((Resource) getCheckedRef()).toLongString()
|
||||||
|
// : getDataTypeName() + " \"" + toString() + '"';
|
||||||
|
return toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the base version.
|
||||||
|
*
|
||||||
|
* @param r the Reference to set.
|
||||||
|
*/
|
||||||
|
public void setRefid(Reference r) {
|
||||||
|
if (name != null
|
||||||
|
|| exists != null
|
||||||
|
|| lastmodified != null
|
||||||
|
|| directory != null
|
||||||
|
|| size != null) {
|
||||||
|
throw tooManyAttributes();
|
||||||
|
}
|
||||||
|
super.setRefid(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a view of this resource that implements the interface given as the argument or null if there is no such
|
||||||
|
* view.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* This allows extension interfaces to be added to resources without growing the number of permutations of
|
||||||
|
* interfaces decorators/adapters need to implement.</p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* This implementation of the method will return the current instance itself if it can be assigned to the given
|
||||||
|
* class.</p>
|
||||||
|
*
|
||||||
|
* @since Ant 1.8.0
|
||||||
|
*/
|
||||||
|
public <T> T as(Class<T> clazz) {
|
||||||
|
return clazz.isAssignableFrom(getClass()) ? clazz.cast(this) : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.types;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import org.owasp.dependencycheck.org.apache.tools.ant.types.resources.FileProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface describing a collection of Resources.
|
||||||
|
* @since Ant 1.7
|
||||||
|
*/
|
||||||
|
public interface ResourceCollection extends Iterable<Resource> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the contents of this collection.
|
||||||
|
* @return all resources in the collection
|
||||||
|
*/
|
||||||
|
Iterator<Resource> iterator();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Learn the number of contained Resources.
|
||||||
|
* @return number of elements as int.
|
||||||
|
*/
|
||||||
|
int size();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicate whether this ResourceCollection is composed entirely of
|
||||||
|
* Resources accessible via local filesystem conventions. If true,
|
||||||
|
* all resources returned from this collection should
|
||||||
|
* respond with a {@link FileProvider} when asked via {@link Resource#as}.
|
||||||
|
* @return whether this is a filesystem-only resource collection.
|
||||||
|
*/
|
||||||
|
boolean isFilesystemOnly();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.types;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this interface should be implemented by classes (Scanners) needing
|
||||||
|
* to deliver information about resources.
|
||||||
|
*
|
||||||
|
* @since Ant 1.5.2
|
||||||
|
*/
|
||||||
|
public interface ResourceFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query a resource (file, zipentry, ...) by name
|
||||||
|
*
|
||||||
|
* @param name relative path of the resource about which
|
||||||
|
* information is sought. Expects "/" to be used as the
|
||||||
|
* directory separator.
|
||||||
|
* @return instance of Resource; the exists attribute of Resource
|
||||||
|
* will tell whether the sought resource exists
|
||||||
|
*/
|
||||||
|
Resource getResource(String name);
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* <html>
|
||||||
|
* <head>
|
||||||
|
* <title>org.owasp.dependencycheck.org.apache.tools.ant.types</title>
|
||||||
|
* </head>
|
||||||
|
* <body>
|
||||||
|
* This is a copy of classes within Apache Ant. The DirectoryScanner
|
||||||
|
* is needed by dependency-check. However, we did not want to make
|
||||||
|
* Ant a dependency. As such, a few files were copied and slightly
|
||||||
|
* modified to remove any references to the Ant Project class.
|
||||||
|
* </body>
|
||||||
|
* </html>
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.types;
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.types.resources;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface to be implemented by "appendable" resources.
|
||||||
|
* @since Ant 1.8
|
||||||
|
*/
|
||||||
|
public interface Appendable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an appending OutputStream.
|
||||||
|
* @return OutputStream
|
||||||
|
* @throws IOException if anything goes wrong
|
||||||
|
*/
|
||||||
|
OutputStream getAppendOutputStream() throws IOException;
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.types.resources;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is an interface that resources that can provide a file should implement.
|
||||||
|
* This is a refactoring of {@link FileResource}, to allow other resources
|
||||||
|
* to act as sources of files (and to make components that only support
|
||||||
|
* file-based resources from only support FileResource resources.
|
||||||
|
* @since Ant 1.8
|
||||||
|
*/
|
||||||
|
public interface FileProvider {
|
||||||
|
/**
|
||||||
|
* Get the file represented by this Resource.
|
||||||
|
* @return the file.
|
||||||
|
*/
|
||||||
|
File getFile();
|
||||||
|
}
|
||||||
@@ -0,0 +1,414 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.types.resources;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import org.owasp.dependencycheck.org.apache.tools.ant.BuildException;
|
||||||
|
import org.owasp.dependencycheck.org.apache.tools.ant.types.Reference;
|
||||||
|
import org.owasp.dependencycheck.org.apache.tools.ant.types.Resource;
|
||||||
|
import org.owasp.dependencycheck.org.apache.tools.ant.types.ResourceFactory;
|
||||||
|
import org.owasp.dependencycheck.org.apache.tools.ant.util.FileUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Resource representation of a File.
|
||||||
|
*
|
||||||
|
* @since Ant 1.7
|
||||||
|
*/
|
||||||
|
public class FileResource extends Resource implements Touchable, FileProvider,
|
||||||
|
ResourceFactory, Appendable {
|
||||||
|
|
||||||
|
private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
|
||||||
|
private static final int NULL_FILE
|
||||||
|
= Resource.getMagicNumber("null file".getBytes());
|
||||||
|
|
||||||
|
private File file;
|
||||||
|
private File baseDir;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor.
|
||||||
|
*/
|
||||||
|
public FileResource() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new FileResource using the specified basedir and relative name.
|
||||||
|
*
|
||||||
|
* @param b the basedir as File.
|
||||||
|
* @param name the relative filename.
|
||||||
|
*/
|
||||||
|
public FileResource(File b, String name) {
|
||||||
|
this.baseDir = b;
|
||||||
|
this.file = FILE_UTILS.resolveFile(b, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new FileResource from a File.
|
||||||
|
*
|
||||||
|
* @param f the File represented.
|
||||||
|
*/
|
||||||
|
public FileResource(File f) {
|
||||||
|
setFile(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Create a new FileResource.
|
||||||
|
// * @param p Project
|
||||||
|
// * @param f File represented
|
||||||
|
// * @since Ant 1.8
|
||||||
|
// */
|
||||||
|
// public FileResource(Project p, File f) {
|
||||||
|
// this(f);
|
||||||
|
// setProject(p);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Constructor for Ant attribute introspection.
|
||||||
|
// * @param p the Project against which to resolve <code>s</code>.
|
||||||
|
// * @param s the absolute or Project-relative filename as a String.
|
||||||
|
// * @see org.apache.tools.ant.IntrospectionHelper
|
||||||
|
// */
|
||||||
|
// public FileResource(Project p, String s) {
|
||||||
|
// this(p, p.resolveFile(s));
|
||||||
|
// }
|
||||||
|
/**
|
||||||
|
* Set the File for this FileResource.
|
||||||
|
*
|
||||||
|
* @param f the File to be represented.
|
||||||
|
*/
|
||||||
|
public void setFile(File f) {
|
||||||
|
checkAttributesAllowed();
|
||||||
|
file = f;
|
||||||
|
if (f != null && (getBaseDir() == null || !FILE_UTILS.isLeadingPath(getBaseDir(), f))) {
|
||||||
|
setBaseDir(f.getParentFile());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the file represented by this FileResource.
|
||||||
|
*
|
||||||
|
* @return the File.
|
||||||
|
*/
|
||||||
|
public File getFile() {
|
||||||
|
// if (isReference()) {
|
||||||
|
// return ((FileResource) getCheckedRef()).getFile();
|
||||||
|
// }
|
||||||
|
// dieOnCircularReference();
|
||||||
|
synchronized (this) {
|
||||||
|
if (file == null) {
|
||||||
|
//try to resolve file set via basedir/name property setters:
|
||||||
|
File d = getBaseDir();
|
||||||
|
String n = super.getName();
|
||||||
|
if (n != null) {
|
||||||
|
setFile(FILE_UTILS.resolveFile(d, n));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the basedir for this FileResource.
|
||||||
|
*
|
||||||
|
* @param b the basedir as File.
|
||||||
|
*/
|
||||||
|
public void setBaseDir(File b) {
|
||||||
|
checkAttributesAllowed();
|
||||||
|
baseDir = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the basedir to which the name is relative.
|
||||||
|
*
|
||||||
|
* @return the basedir as File.
|
||||||
|
*/
|
||||||
|
public File getBaseDir() {
|
||||||
|
// if (isReference()) {
|
||||||
|
// return ((FileResource) getCheckedRef()).getBaseDir();
|
||||||
|
// }
|
||||||
|
// dieOnCircularReference();
|
||||||
|
return baseDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the super version.
|
||||||
|
*
|
||||||
|
* @param r the Reference to set.
|
||||||
|
*/
|
||||||
|
public void setRefid(Reference r) {
|
||||||
|
if (file != null || baseDir != null) {
|
||||||
|
throw tooManyAttributes();
|
||||||
|
}
|
||||||
|
super.setRefid(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name of this FileResource. If the basedir is set, the name will be relative to that. Otherwise the
|
||||||
|
* basename only will be returned.
|
||||||
|
*
|
||||||
|
* @return the name of this resource.
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
// if (isReference()) {
|
||||||
|
// return ((Resource) getCheckedRef()).getName();
|
||||||
|
// }
|
||||||
|
File b = getBaseDir();
|
||||||
|
return b == null ? getNotNullFile().getName()
|
||||||
|
: FILE_UTILS.removeLeadingPath(b, getNotNullFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Learn whether this file exists.
|
||||||
|
*
|
||||||
|
* @return true if this resource exists.
|
||||||
|
*/
|
||||||
|
public boolean isExists() {
|
||||||
|
// return isReference() ? ((Resource) getCheckedRef()).isExists()
|
||||||
|
// : getNotNullFile().exists();
|
||||||
|
return getNotNullFile().exists();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the modification time in milliseconds since 01.01.1970 .
|
||||||
|
*
|
||||||
|
* @return 0 if the resource does not exist.
|
||||||
|
*/
|
||||||
|
public long getLastModified() {
|
||||||
|
// return isReference()
|
||||||
|
// ? ((Resource) getCheckedRef()).getLastModified()
|
||||||
|
// : getNotNullFile().lastModified();
|
||||||
|
return getNotNullFile().lastModified();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Learn whether the resource is a directory.
|
||||||
|
*
|
||||||
|
* @return boolean flag indicating if the resource is a directory.
|
||||||
|
*/
|
||||||
|
public boolean isDirectory() {
|
||||||
|
// return isReference() ? ((Resource) getCheckedRef()).isDirectory()
|
||||||
|
// : getNotNullFile().isDirectory();
|
||||||
|
return getNotNullFile().isDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the size of this Resource.
|
||||||
|
*
|
||||||
|
* @return the size, as a long, 0 if the Resource does not exist.
|
||||||
|
*/
|
||||||
|
public long getSize() {
|
||||||
|
// return isReference() ? ((Resource) getCheckedRef()).getSize()
|
||||||
|
// : getNotNullFile().length();
|
||||||
|
return getNotNullFile().length();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an InputStream for reading the contents of this Resource.
|
||||||
|
*
|
||||||
|
* @return an InputStream object.
|
||||||
|
* @throws IOException if an error occurs.
|
||||||
|
*/
|
||||||
|
public InputStream getInputStream() throws IOException {
|
||||||
|
// return isReference()
|
||||||
|
// ? ((Resource) getCheckedRef()).getInputStream()
|
||||||
|
// : new FileInputStream(getNotNullFile());
|
||||||
|
return new FileInputStream(getNotNullFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an OutputStream for the Resource.
|
||||||
|
*
|
||||||
|
* @return an OutputStream to which content can be written.
|
||||||
|
* @throws IOException if unable to provide the content of this Resource as a stream.
|
||||||
|
* @throws UnsupportedOperationException if OutputStreams are not supported for this Resource type.
|
||||||
|
*/
|
||||||
|
public OutputStream getOutputStream() throws IOException {
|
||||||
|
// if (isReference()) {
|
||||||
|
// return ((FileResource) getCheckedRef()).getOutputStream();
|
||||||
|
// }
|
||||||
|
return getOutputStream(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public OutputStream getAppendOutputStream() throws IOException {
|
||||||
|
// if (isReference()) {
|
||||||
|
// return ((FileResource) getCheckedRef()).getAppendOutputStream();
|
||||||
|
// }
|
||||||
|
return getOutputStream(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private OutputStream getOutputStream(boolean append) throws IOException {
|
||||||
|
File f = getNotNullFile();
|
||||||
|
if (f.exists()) {
|
||||||
|
if (f.isFile() && !append) {
|
||||||
|
f.delete();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
File p = f.getParentFile();
|
||||||
|
if (p != null && !(p.exists())) {
|
||||||
|
p.mkdirs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return append ? new FileOutputStream(f.getAbsolutePath(), true) : new FileOutputStream(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare this FileResource to another Resource.
|
||||||
|
*
|
||||||
|
* @param another the other Resource against which to compare.
|
||||||
|
* @return a negative integer, zero, or a positive integer as this FileResource is less than, equal to, or greater
|
||||||
|
* than the specified Resource.
|
||||||
|
*/
|
||||||
|
public int compareTo(Resource another) {
|
||||||
|
// if (isReference()) {
|
||||||
|
// return ((Resource) getCheckedRef()).compareTo(another);
|
||||||
|
// }
|
||||||
|
if (this.equals(another)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
FileProvider otherFP = another.as(FileProvider.class);
|
||||||
|
if (otherFP != null) {
|
||||||
|
File f = getFile();
|
||||||
|
if (f == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
File of = otherFP.getFile();
|
||||||
|
if (of == null) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return f.compareTo(of);
|
||||||
|
}
|
||||||
|
return super.compareTo(another);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare another Object to this FileResource for equality.
|
||||||
|
*
|
||||||
|
* @param another the other Object to compare.
|
||||||
|
* @return true if another is a FileResource representing the same file.
|
||||||
|
*/
|
||||||
|
public boolean equals(Object another) {
|
||||||
|
if (this == another) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// if (isReference()) {
|
||||||
|
// return getCheckedRef().equals(another);
|
||||||
|
// }
|
||||||
|
if (another == null || !(another.getClass().equals(getClass()))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
FileResource otherfr = (FileResource) another;
|
||||||
|
return getFile() == null
|
||||||
|
? otherfr.getFile() == null
|
||||||
|
: getFile().equals(otherfr.getFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the hash code for this Resource.
|
||||||
|
*
|
||||||
|
* @return hash code as int.
|
||||||
|
*/
|
||||||
|
public int hashCode() {
|
||||||
|
// if (isReference()) {
|
||||||
|
// return getCheckedRef().hashCode();
|
||||||
|
// }
|
||||||
|
return MAGIC * (getFile() == null ? NULL_FILE : getFile().hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the string representation of this Resource.
|
||||||
|
*
|
||||||
|
* @return this FileResource formatted as a String.
|
||||||
|
*/
|
||||||
|
public String toString() {
|
||||||
|
// if (isReference()) {
|
||||||
|
// return getCheckedRef().toString();
|
||||||
|
// }
|
||||||
|
if (file == null) {
|
||||||
|
return "(unbound file resource)";
|
||||||
|
}
|
||||||
|
String absolutePath = file.getAbsolutePath();
|
||||||
|
return FILE_UTILS.normalize(absolutePath).getAbsolutePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fulfill the ResourceCollection contract.
|
||||||
|
*
|
||||||
|
* @return whether this Resource is a FileResource.
|
||||||
|
*/
|
||||||
|
public boolean isFilesystemOnly() {
|
||||||
|
// if (isReference()) {
|
||||||
|
// return ((FileResource) getCheckedRef()).isFilesystemOnly();
|
||||||
|
// }
|
||||||
|
// dieOnCircularReference();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implement the Touchable interface.
|
||||||
|
*
|
||||||
|
* @param modTime new last modification time.
|
||||||
|
*/
|
||||||
|
public void touch(long modTime) {
|
||||||
|
// if (isReference()) {
|
||||||
|
// ((FileResource) getCheckedRef()).touch(modTime);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
if (!getNotNullFile().setLastModified(modTime)) {
|
||||||
|
//log("Failed to change file modification time", Project.MSG_WARN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the file represented by this FileResource, ensuring it is not null.
|
||||||
|
*
|
||||||
|
* @return the not-null File.
|
||||||
|
* @throws BuildException if file is null.
|
||||||
|
*/
|
||||||
|
protected File getNotNullFile() {
|
||||||
|
if (getFile() == null) {
|
||||||
|
throw new BuildException("file attribute is null!");
|
||||||
|
}
|
||||||
|
// dieOnCircularReference();
|
||||||
|
return getFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new resource that matches a relative or absolute path. If the current instance has a compatible baseDir
|
||||||
|
* attribute, it is copied.
|
||||||
|
*
|
||||||
|
* @param path relative/absolute path to a resource
|
||||||
|
* @return a new resource of type FileResource
|
||||||
|
* @throws BuildException if desired
|
||||||
|
* @since Ant1.8
|
||||||
|
*/
|
||||||
|
public Resource getResource(String path) {
|
||||||
|
File newfile = FILE_UTILS.resolveFile(getFile(), path);
|
||||||
|
FileResource fileResource = new FileResource(newfile);
|
||||||
|
if (FILE_UTILS.isLeadingPath(getBaseDir(), newfile)) {
|
||||||
|
fileResource.setBaseDir(getBaseDir());
|
||||||
|
}
|
||||||
|
return fileResource;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.types.resources;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface to be implemented by "touchable" resources;
|
||||||
|
* that is, those whose modification time can be altered.
|
||||||
|
* @since Ant 1.7
|
||||||
|
*/
|
||||||
|
public interface Touchable {
|
||||||
|
/**
|
||||||
|
* Method called to "touch" the resource.
|
||||||
|
* @param modTime the time to set the modified "field" of the resource,
|
||||||
|
* measured in milliseconds since the epoch.
|
||||||
|
*/
|
||||||
|
void touch(long modTime);
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* <html>
|
||||||
|
* <head>
|
||||||
|
* <title>org.owasp.dependencycheck.org.apache.tools.ant.types.resources</title>
|
||||||
|
* </head>
|
||||||
|
* <body>
|
||||||
|
* This is a copy of classes within Apache Ant. The DirectoryScanner
|
||||||
|
* is needed by dependency-check. However, we did not want to make
|
||||||
|
* Ant a dependency. As such, a few files were copied and slightly
|
||||||
|
* modified to remove any references to the Ant Project class.
|
||||||
|
* </body>
|
||||||
|
* </html>
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.types.resources;
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.types.selectors;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import org.owasp.dependencycheck.org.apache.tools.ant.BuildException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the interface to be used by all selectors.
|
||||||
|
*
|
||||||
|
* @since 1.5
|
||||||
|
*/
|
||||||
|
public interface FileSelector {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that each selector will implement to create their
|
||||||
|
* selection behaviour. If there is a problem with the setup
|
||||||
|
* of a selector, it can throw a BuildException to indicate
|
||||||
|
* the problem.
|
||||||
|
*
|
||||||
|
* @param basedir A java.io.File object for the base directory
|
||||||
|
* @param filename The name of the file to check
|
||||||
|
* @param file A File object for this filename
|
||||||
|
* @return whether the file should be selected or not
|
||||||
|
* @exception BuildException if the selector was not configured correctly
|
||||||
|
*/
|
||||||
|
boolean isSelected(File basedir, String filename, File file)
|
||||||
|
throws BuildException;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.types.selectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface used to describe the actions required by any type of
|
||||||
|
* directory scanner that supports Selectors.
|
||||||
|
*
|
||||||
|
* @since 1.5
|
||||||
|
*/
|
||||||
|
public interface SelectorScanner {
|
||||||
|
/**
|
||||||
|
* Sets the selectors the scanner should use.
|
||||||
|
*
|
||||||
|
* @param selectors the list of selectors
|
||||||
|
*/
|
||||||
|
void setSelectors(FileSelector[] selectors);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directories which were selected out of a scan.
|
||||||
|
*
|
||||||
|
* @return list of directories not selected
|
||||||
|
*/
|
||||||
|
String[] getDeselectedDirectories();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Files which were selected out of a scan.
|
||||||
|
*
|
||||||
|
* @return list of files not selected
|
||||||
|
*/
|
||||||
|
String[] getDeselectedFiles();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,695 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.types.selectors;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import org.owasp.dependencycheck.org.apache.tools.ant.types.Resource;
|
||||||
|
import org.owasp.dependencycheck.org.apache.tools.ant.util.FileUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>This is a utility class used by selectors and DirectoryScanner. The
|
||||||
|
* functionality more properly belongs just to selectors, but unfortunately
|
||||||
|
* DirectoryScanner exposed these as protected methods. Thus we have to
|
||||||
|
* support any subclasses of DirectoryScanner that may access these methods.
|
||||||
|
* </p>
|
||||||
|
* <p>This is a Singleton.</p>
|
||||||
|
*
|
||||||
|
* @since 1.5
|
||||||
|
*/
|
||||||
|
public final class SelectorUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The pattern that matches an arbitrary number of directories.
|
||||||
|
* @since Ant 1.8.0
|
||||||
|
*/
|
||||||
|
public static final String DEEP_TREE_MATCH = "**";
|
||||||
|
|
||||||
|
private static final SelectorUtils instance = new SelectorUtils();
|
||||||
|
private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private Constructor
|
||||||
|
*/
|
||||||
|
private SelectorUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the instance of the Singleton.
|
||||||
|
* @return singleton instance
|
||||||
|
*/
|
||||||
|
public static SelectorUtils getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests whether or not a given path matches the start of a given
|
||||||
|
* pattern up to the first "**".
|
||||||
|
* <p>
|
||||||
|
* This is not a general purpose test and should only be used if you
|
||||||
|
* can live with false positives. For example, <code>pattern=**\a</code>
|
||||||
|
* and <code>str=b</code> will yield <code>true</code>.
|
||||||
|
*
|
||||||
|
* @param pattern The pattern to match against. Must not be
|
||||||
|
* <code>null</code>.
|
||||||
|
* @param str The path to match, as a String. Must not be
|
||||||
|
* <code>null</code>.
|
||||||
|
*
|
||||||
|
* @return whether or not a given path matches the start of a given
|
||||||
|
* pattern up to the first "**".
|
||||||
|
*/
|
||||||
|
public static boolean matchPatternStart(String pattern, String str) {
|
||||||
|
return matchPatternStart(pattern, str, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests whether or not a given path matches the start of a given
|
||||||
|
* pattern up to the first "**".
|
||||||
|
* <p>
|
||||||
|
* This is not a general purpose test and should only be used if you
|
||||||
|
* can live with false positives. For example, <code>pattern=**\a</code>
|
||||||
|
* and <code>str=b</code> will yield <code>true</code>.
|
||||||
|
*
|
||||||
|
* @param pattern The pattern to match against. Must not be
|
||||||
|
* <code>null</code>.
|
||||||
|
* @param str The path to match, as a String. Must not be
|
||||||
|
* <code>null</code>.
|
||||||
|
* @param isCaseSensitive Whether or not matching should be performed
|
||||||
|
* case sensitively.
|
||||||
|
*
|
||||||
|
* @return whether or not a given path matches the start of a given
|
||||||
|
* pattern up to the first "**".
|
||||||
|
*/
|
||||||
|
public static boolean matchPatternStart(String pattern, String str,
|
||||||
|
boolean isCaseSensitive) {
|
||||||
|
// When str starts with a File.separator, pattern has to start with a
|
||||||
|
// File.separator.
|
||||||
|
// When pattern starts with a File.separator, str has to start with a
|
||||||
|
// File.separator.
|
||||||
|
if (str.startsWith(File.separator)
|
||||||
|
!= pattern.startsWith(File.separator)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] patDirs = tokenizePathAsArray(pattern);
|
||||||
|
String[] strDirs = tokenizePathAsArray(str);
|
||||||
|
return matchPatternStart(patDirs, strDirs, isCaseSensitive);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests whether or not a given path matches the start of a given
|
||||||
|
* pattern up to the first "**".
|
||||||
|
* <p>
|
||||||
|
* This is not a general purpose test and should only be used if you
|
||||||
|
* can live with false positives. For example, <code>pattern=**\a</code>
|
||||||
|
* and <code>str=b</code> will yield <code>true</code>.
|
||||||
|
*
|
||||||
|
* @param patDirs The tokenized pattern to match against. Must not be
|
||||||
|
* <code>null</code>.
|
||||||
|
* @param strDirs The tokenized path to match. Must not be
|
||||||
|
* <code>null</code>.
|
||||||
|
* @param isCaseSensitive Whether or not matching should be performed
|
||||||
|
* case sensitively.
|
||||||
|
*
|
||||||
|
* @return whether or not a given path matches the start of a given
|
||||||
|
* pattern up to the first "**".
|
||||||
|
*/
|
||||||
|
static boolean matchPatternStart(String[] patDirs, String[] strDirs,
|
||||||
|
boolean isCaseSensitive) {
|
||||||
|
int patIdxStart = 0;
|
||||||
|
int patIdxEnd = patDirs.length - 1;
|
||||||
|
int strIdxStart = 0;
|
||||||
|
int strIdxEnd = strDirs.length - 1;
|
||||||
|
|
||||||
|
// up to first '**'
|
||||||
|
while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) {
|
||||||
|
String patDir = patDirs[patIdxStart];
|
||||||
|
if (patDir.equals(DEEP_TREE_MATCH)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!match(patDir, strDirs[strIdxStart], isCaseSensitive)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
patIdxStart++;
|
||||||
|
strIdxStart++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckStyle:SimplifyBooleanReturnCheck OFF
|
||||||
|
// Check turned off as the code needs the comments for the various
|
||||||
|
// code paths.
|
||||||
|
if (strIdxStart > strIdxEnd) {
|
||||||
|
// String is exhausted
|
||||||
|
return true;
|
||||||
|
} else if (patIdxStart > patIdxEnd) {
|
||||||
|
// String not exhausted, but pattern is. Failure.
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
// pattern now holds ** while string is not exhausted
|
||||||
|
// this will generate false positives but we can live with that.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests whether or not a given path matches a given pattern.
|
||||||
|
*
|
||||||
|
* If you need to call this method multiple times with the same
|
||||||
|
* pattern you should rather use TokenizedPath
|
||||||
|
*
|
||||||
|
* @see TokenizedPath
|
||||||
|
*
|
||||||
|
* @param pattern The pattern to match against. Must not be
|
||||||
|
* <code>null</code>.
|
||||||
|
* @param str The path to match, as a String. Must not be
|
||||||
|
* <code>null</code>.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if the pattern matches against the string,
|
||||||
|
* or <code>false</code> otherwise.
|
||||||
|
*/
|
||||||
|
public static boolean matchPath(String pattern, String str) {
|
||||||
|
String[] patDirs = tokenizePathAsArray(pattern);
|
||||||
|
return matchPath(patDirs, tokenizePathAsArray(str), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests whether or not a given path matches a given pattern.
|
||||||
|
*
|
||||||
|
* If you need to call this method multiple times with the same
|
||||||
|
* pattern you should rather use TokenizedPattern
|
||||||
|
*
|
||||||
|
* @see TokenizedPattern
|
||||||
|
*
|
||||||
|
* @param pattern The pattern to match against. Must not be
|
||||||
|
* <code>null</code>.
|
||||||
|
* @param str The path to match, as a String. Must not be
|
||||||
|
* <code>null</code>.
|
||||||
|
* @param isCaseSensitive Whether or not matching should be performed
|
||||||
|
* case sensitively.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if the pattern matches against the string,
|
||||||
|
* or <code>false</code> otherwise.
|
||||||
|
*/
|
||||||
|
public static boolean matchPath(String pattern, String str,
|
||||||
|
boolean isCaseSensitive) {
|
||||||
|
String[] patDirs = tokenizePathAsArray(pattern);
|
||||||
|
return matchPath(patDirs, tokenizePathAsArray(str), isCaseSensitive);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Core implementation of matchPath. It is isolated so that it
|
||||||
|
* can be called from TokenizedPattern.
|
||||||
|
*/
|
||||||
|
static boolean matchPath(String[] tokenizedPattern, String[] strDirs,
|
||||||
|
boolean isCaseSensitive) {
|
||||||
|
int patIdxStart = 0;
|
||||||
|
int patIdxEnd = tokenizedPattern.length - 1;
|
||||||
|
int strIdxStart = 0;
|
||||||
|
int strIdxEnd = strDirs.length - 1;
|
||||||
|
|
||||||
|
// up to first '**'
|
||||||
|
while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) {
|
||||||
|
String patDir = tokenizedPattern[patIdxStart];
|
||||||
|
if (patDir.equals(DEEP_TREE_MATCH)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!match(patDir, strDirs[strIdxStart], isCaseSensitive)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
patIdxStart++;
|
||||||
|
strIdxStart++;
|
||||||
|
}
|
||||||
|
if (strIdxStart > strIdxEnd) {
|
||||||
|
// String is exhausted
|
||||||
|
for (int i = patIdxStart; i <= patIdxEnd; i++) {
|
||||||
|
if (!tokenizedPattern[i].equals(DEEP_TREE_MATCH)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
if (patIdxStart > patIdxEnd) {
|
||||||
|
// String not exhausted, but pattern is. Failure.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// up to last '**'
|
||||||
|
while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) {
|
||||||
|
String patDir = tokenizedPattern[patIdxEnd];
|
||||||
|
if (patDir.equals(DEEP_TREE_MATCH)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!match(patDir, strDirs[strIdxEnd], isCaseSensitive)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
patIdxEnd--;
|
||||||
|
strIdxEnd--;
|
||||||
|
}
|
||||||
|
if (strIdxStart > strIdxEnd) {
|
||||||
|
// String is exhausted
|
||||||
|
for (int i = patIdxStart; i <= patIdxEnd; i++) {
|
||||||
|
if (!tokenizedPattern[i].equals(DEEP_TREE_MATCH)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {
|
||||||
|
int patIdxTmp = -1;
|
||||||
|
for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
|
||||||
|
if (tokenizedPattern[i].equals(DEEP_TREE_MATCH)) {
|
||||||
|
patIdxTmp = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (patIdxTmp == patIdxStart + 1) {
|
||||||
|
// '**/**' situation, so skip one
|
||||||
|
patIdxStart++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Find the pattern between padIdxStart & padIdxTmp in str between
|
||||||
|
// strIdxStart & strIdxEnd
|
||||||
|
int patLength = (patIdxTmp - patIdxStart - 1);
|
||||||
|
int strLength = (strIdxEnd - strIdxStart + 1);
|
||||||
|
int foundIdx = -1;
|
||||||
|
strLoop:
|
||||||
|
for (int i = 0; i <= strLength - patLength; i++) {
|
||||||
|
for (int j = 0; j < patLength; j++) {
|
||||||
|
String subPat = tokenizedPattern[patIdxStart + j + 1];
|
||||||
|
String subStr = strDirs[strIdxStart + i + j];
|
||||||
|
if (!match(subPat, subStr, isCaseSensitive)) {
|
||||||
|
continue strLoop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foundIdx = strIdxStart + i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (foundIdx == -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
patIdxStart = patIdxTmp;
|
||||||
|
strIdxStart = foundIdx + patLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = patIdxStart; i <= patIdxEnd; i++) {
|
||||||
|
if (!tokenizedPattern[i].equals(DEEP_TREE_MATCH)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests whether or not a string matches against a pattern.
|
||||||
|
* The pattern may contain two special characters:<br>
|
||||||
|
* '*' means zero or more characters<br>
|
||||||
|
* '?' means one and only one character
|
||||||
|
*
|
||||||
|
* @param pattern The pattern to match against.
|
||||||
|
* Must not be <code>null</code>.
|
||||||
|
* @param str The string which must be matched against the pattern.
|
||||||
|
* Must not be <code>null</code>.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if the string matches against the pattern,
|
||||||
|
* or <code>false</code> otherwise.
|
||||||
|
*/
|
||||||
|
public static boolean match(String pattern, String str) {
|
||||||
|
return match(pattern, str, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests whether or not a string matches against a pattern.
|
||||||
|
* The pattern may contain two special characters:<br>
|
||||||
|
* '*' means zero or more characters<br>
|
||||||
|
* '?' means one and only one character
|
||||||
|
*
|
||||||
|
* @param pattern The pattern to match against.
|
||||||
|
* Must not be <code>null</code>.
|
||||||
|
* @param str The string which must be matched against the pattern.
|
||||||
|
* Must not be <code>null</code>.
|
||||||
|
* @param caseSensitive Whether or not matching should be performed
|
||||||
|
* case sensitively.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if the string matches against the pattern,
|
||||||
|
* or <code>false</code> otherwise.
|
||||||
|
*/
|
||||||
|
public static boolean match(String pattern, String str,
|
||||||
|
boolean caseSensitive) {
|
||||||
|
char[] patArr = pattern.toCharArray();
|
||||||
|
char[] strArr = str.toCharArray();
|
||||||
|
int patIdxStart = 0;
|
||||||
|
int patIdxEnd = patArr.length - 1;
|
||||||
|
int strIdxStart = 0;
|
||||||
|
int strIdxEnd = strArr.length - 1;
|
||||||
|
char ch;
|
||||||
|
|
||||||
|
boolean containsStar = false;
|
||||||
|
for (int i = 0; i < patArr.length; i++) {
|
||||||
|
if (patArr[i] == '*') {
|
||||||
|
containsStar = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!containsStar) {
|
||||||
|
// No '*'s, so we make a shortcut
|
||||||
|
if (patIdxEnd != strIdxEnd) {
|
||||||
|
return false; // Pattern and string do not have the same size
|
||||||
|
}
|
||||||
|
for (int i = 0; i <= patIdxEnd; i++) {
|
||||||
|
ch = patArr[i];
|
||||||
|
if (ch != '?') {
|
||||||
|
if (different(caseSensitive, ch, strArr[i])) {
|
||||||
|
return false; // Character mismatch
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true; // String matches against pattern
|
||||||
|
}
|
||||||
|
|
||||||
|
if (patIdxEnd == 0) {
|
||||||
|
return true; // Pattern contains only '*', which matches anything
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process characters before first star
|
||||||
|
while (true) {
|
||||||
|
ch = patArr[patIdxStart];
|
||||||
|
if (ch == '*' || strIdxStart > strIdxEnd) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ch != '?') {
|
||||||
|
if (different(caseSensitive, ch, strArr[strIdxStart])) {
|
||||||
|
return false; // Character mismatch
|
||||||
|
}
|
||||||
|
}
|
||||||
|
patIdxStart++;
|
||||||
|
strIdxStart++;
|
||||||
|
}
|
||||||
|
if (strIdxStart > strIdxEnd) {
|
||||||
|
// All characters in the string are used. Check if only '*'s are
|
||||||
|
// left in the pattern. If so, we succeeded. Otherwise failure.
|
||||||
|
return allStars(patArr, patIdxStart, patIdxEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process characters after last star
|
||||||
|
while (true) {
|
||||||
|
ch = patArr[patIdxEnd];
|
||||||
|
if (ch == '*' || strIdxStart > strIdxEnd) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ch != '?') {
|
||||||
|
if (different(caseSensitive, ch, strArr[strIdxEnd])) {
|
||||||
|
return false; // Character mismatch
|
||||||
|
}
|
||||||
|
}
|
||||||
|
patIdxEnd--;
|
||||||
|
strIdxEnd--;
|
||||||
|
}
|
||||||
|
if (strIdxStart > strIdxEnd) {
|
||||||
|
// All characters in the string are used. Check if only '*'s are
|
||||||
|
// left in the pattern. If so, we succeeded. Otherwise failure.
|
||||||
|
return allStars(patArr, patIdxStart, patIdxEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// process pattern between stars. padIdxStart and patIdxEnd point
|
||||||
|
// always to a '*'.
|
||||||
|
while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {
|
||||||
|
int patIdxTmp = -1;
|
||||||
|
for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
|
||||||
|
if (patArr[i] == '*') {
|
||||||
|
patIdxTmp = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (patIdxTmp == patIdxStart + 1) {
|
||||||
|
// Two stars next to each other, skip the first one.
|
||||||
|
patIdxStart++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Find the pattern between padIdxStart & padIdxTmp in str between
|
||||||
|
// strIdxStart & strIdxEnd
|
||||||
|
int patLength = (patIdxTmp - patIdxStart - 1);
|
||||||
|
int strLength = (strIdxEnd - strIdxStart + 1);
|
||||||
|
int foundIdx = -1;
|
||||||
|
strLoop:
|
||||||
|
for (int i = 0; i <= strLength - patLength; i++) {
|
||||||
|
for (int j = 0; j < patLength; j++) {
|
||||||
|
ch = patArr[patIdxStart + j + 1];
|
||||||
|
if (ch != '?') {
|
||||||
|
if (different(caseSensitive, ch,
|
||||||
|
strArr[strIdxStart + i + j])) {
|
||||||
|
continue strLoop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foundIdx = strIdxStart + i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (foundIdx == -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
patIdxStart = patIdxTmp;
|
||||||
|
strIdxStart = foundIdx + patLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
// All characters in the string are used. Check if only '*'s are left
|
||||||
|
// in the pattern. If so, we succeeded. Otherwise failure.
|
||||||
|
return allStars(patArr, patIdxStart, patIdxEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean allStars(char[] chars, int start, int end) {
|
||||||
|
for (int i = start; i <= end; ++i) {
|
||||||
|
if (chars[i] != '*') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean different(
|
||||||
|
boolean caseSensitive, char ch, char other) {
|
||||||
|
return caseSensitive
|
||||||
|
? ch != other
|
||||||
|
: Character.toUpperCase(ch) != Character.toUpperCase(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Breaks a path up into a Vector of path elements, tokenizing on
|
||||||
|
* <code>File.separator</code>.
|
||||||
|
*
|
||||||
|
* @param path Path to tokenize. Must not be <code>null</code>.
|
||||||
|
*
|
||||||
|
* @return a Vector of path elements from the tokenized path
|
||||||
|
*/
|
||||||
|
public static Vector<String> tokenizePath(String path) {
|
||||||
|
return tokenizePath(path, File.separator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Breaks a path up into a Vector of path elements, tokenizing on
|
||||||
|
*
|
||||||
|
* @param path Path to tokenize. Must not be <code>null</code>.
|
||||||
|
* @param separator the separator against which to tokenize.
|
||||||
|
*
|
||||||
|
* @return a Vector of path elements from the tokenized path
|
||||||
|
* @since Ant 1.6
|
||||||
|
*/
|
||||||
|
public static Vector<String> tokenizePath(String path, String separator) {
|
||||||
|
Vector<String> ret = new Vector<String>();
|
||||||
|
if (FileUtils.isAbsolutePath(path)) {
|
||||||
|
String[] s = FILE_UTILS.dissect(path);
|
||||||
|
ret.add(s[0]);
|
||||||
|
path = s[1];
|
||||||
|
}
|
||||||
|
StringTokenizer st = new StringTokenizer(path, separator);
|
||||||
|
while (st.hasMoreTokens()) {
|
||||||
|
ret.addElement(st.nextToken());
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as {@link #tokenizePath tokenizePath} but hopefully faster.
|
||||||
|
*/
|
||||||
|
/*package*/ static String[] tokenizePathAsArray(String path) {
|
||||||
|
String root = null;
|
||||||
|
if (FileUtils.isAbsolutePath(path)) {
|
||||||
|
String[] s = FILE_UTILS.dissect(path);
|
||||||
|
root = s[0];
|
||||||
|
path = s[1];
|
||||||
|
}
|
||||||
|
char sep = File.separatorChar;
|
||||||
|
int start = 0;
|
||||||
|
int len = path.length();
|
||||||
|
int count = 0;
|
||||||
|
for (int pos = 0; pos < len; pos++) {
|
||||||
|
if (path.charAt(pos) == sep) {
|
||||||
|
if (pos != start) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
start = pos + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (len != start) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
String[] l = new String[count + ((root == null) ? 0 : 1)];
|
||||||
|
|
||||||
|
if (root != null) {
|
||||||
|
l[0] = root;
|
||||||
|
count = 1;
|
||||||
|
} else {
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
start = 0;
|
||||||
|
for (int pos = 0; pos < len; pos++) {
|
||||||
|
if (path.charAt(pos) == sep) {
|
||||||
|
if (pos != start) {
|
||||||
|
String tok = path.substring(start, pos);
|
||||||
|
l[count++] = tok;
|
||||||
|
}
|
||||||
|
start = pos + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (len != start) {
|
||||||
|
String tok = path.substring(start);
|
||||||
|
l[count/*++*/] = tok;
|
||||||
|
}
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns dependency information on these two files. If src has been
|
||||||
|
* modified later than target, it returns true. If target doesn't exist,
|
||||||
|
* it likewise returns true. Otherwise, target is newer than src and
|
||||||
|
* is not out of date, thus the method returns false. It also returns
|
||||||
|
* false if the src file doesn't even exist, since how could the
|
||||||
|
* target then be out of date.
|
||||||
|
*
|
||||||
|
* @param src the original file
|
||||||
|
* @param target the file being compared against
|
||||||
|
* @param granularity the amount in seconds of slack we will give in
|
||||||
|
* determining out of dateness
|
||||||
|
* @return whether the target is out of date
|
||||||
|
*/
|
||||||
|
public static boolean isOutOfDate(File src, File target, int granularity) {
|
||||||
|
if (!src.exists()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!target.exists()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ((src.lastModified() - granularity) > target.lastModified()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns dependency information on these two resources. If src has been
|
||||||
|
* modified later than target, it returns true. If target doesn't exist,
|
||||||
|
* it likewise returns true. Otherwise, target is newer than src and
|
||||||
|
* is not out of date, thus the method returns false. It also returns
|
||||||
|
* false if the src file doesn't even exist, since how could the
|
||||||
|
* target then be out of date.
|
||||||
|
*
|
||||||
|
* @param src the original resource
|
||||||
|
* @param target the resource being compared against
|
||||||
|
* @param granularity the int amount in seconds of slack we will give in
|
||||||
|
* determining out of dateness
|
||||||
|
* @return whether the target is out of date
|
||||||
|
*/
|
||||||
|
public static boolean isOutOfDate(Resource src, Resource target,
|
||||||
|
int granularity) {
|
||||||
|
return isOutOfDate(src, target, (long) granularity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns dependency information on these two resources. If src has been
|
||||||
|
* modified later than target, it returns true. If target doesn't exist,
|
||||||
|
* it likewise returns true. Otherwise, target is newer than src and
|
||||||
|
* is not out of date, thus the method returns false. It also returns
|
||||||
|
* false if the src file doesn't even exist, since how could the
|
||||||
|
* target then be out of date.
|
||||||
|
*
|
||||||
|
* @param src the original resource
|
||||||
|
* @param target the resource being compared against
|
||||||
|
* @param granularity the long amount in seconds of slack we will give in
|
||||||
|
* determining out of dateness
|
||||||
|
* @return whether the target is out of date
|
||||||
|
*/
|
||||||
|
public static boolean isOutOfDate(Resource src, Resource target, long granularity) {
|
||||||
|
long sourceLastModified = src.getLastModified();
|
||||||
|
long targetLastModified = target.getLastModified();
|
||||||
|
return src.isExists()
|
||||||
|
&& (sourceLastModified == Resource.UNKNOWN_DATETIME
|
||||||
|
|| targetLastModified == Resource.UNKNOWN_DATETIME
|
||||||
|
|| (sourceLastModified - granularity) > targetLastModified);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "Flattens" a string by removing all whitespace (space, tab, linefeed,
|
||||||
|
* carriage return, and formfeed). This uses StringTokenizer and the
|
||||||
|
* default set of tokens as documented in the single argument constructor.
|
||||||
|
*
|
||||||
|
* @param input a String to remove all whitespace.
|
||||||
|
* @return a String that has had all whitespace removed.
|
||||||
|
*/
|
||||||
|
public static String removeWhitespace(String input) {
|
||||||
|
StringBuffer result = new StringBuffer();
|
||||||
|
if (input != null) {
|
||||||
|
StringTokenizer st = new StringTokenizer(input);
|
||||||
|
while (st.hasMoreTokens()) {
|
||||||
|
result.append(st.nextToken());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests if a string contains stars or question marks
|
||||||
|
* @param input a String which one wants to test for containing wildcard
|
||||||
|
* @return true if the string contains at least a star or a question mark
|
||||||
|
*/
|
||||||
|
public static boolean hasWildcards(String input) {
|
||||||
|
return (input.indexOf('*') != -1 || input.indexOf('?') != -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* removes from a pattern all tokens to the right containing wildcards
|
||||||
|
* @param input the input string
|
||||||
|
* @return the leftmost part of the pattern without wildcards
|
||||||
|
*/
|
||||||
|
public static String rtrimWildcardTokens(String input) {
|
||||||
|
return new TokenizedPattern(input).rtrimWildcardTokens().toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,219 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.types.selectors;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import org.owasp.dependencycheck.org.apache.tools.ant.BuildException;
|
||||||
|
import org.owasp.dependencycheck.org.apache.tools.ant.util.FileUtils;
|
||||||
|
import org.owasp.dependencycheck.org.apache.tools.ant.util.SymbolicLinkUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Container for a path that has been split into its components.
|
||||||
|
* @since 1.8.0
|
||||||
|
*/
|
||||||
|
public class TokenizedPath {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instance that holds no tokens at all.
|
||||||
|
*/
|
||||||
|
public static final TokenizedPath EMPTY_PATH =
|
||||||
|
new TokenizedPath("", new String[0]);
|
||||||
|
|
||||||
|
/** Helper. */
|
||||||
|
private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
|
||||||
|
/** Helper. */
|
||||||
|
private static final SymbolicLinkUtils SYMLINK_UTILS =
|
||||||
|
SymbolicLinkUtils.getSymbolicLinkUtils();
|
||||||
|
/** iterations for case-sensitive scanning. */
|
||||||
|
private static final boolean[] CS_SCAN_ONLY = new boolean[] {true};
|
||||||
|
/** iterations for non-case-sensitive scanning. */
|
||||||
|
private static final boolean[] CS_THEN_NON_CS = new boolean[] {true, false};
|
||||||
|
|
||||||
|
private final String path;
|
||||||
|
private final String[] tokenizedPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the TokenizedPath by parsing it.
|
||||||
|
* @param path The path to tokenize. Must not be
|
||||||
|
* <code>null</code>.
|
||||||
|
*/
|
||||||
|
public TokenizedPath(String path) {
|
||||||
|
this(path, SelectorUtils.tokenizePathAsArray(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new path as a child of another path.
|
||||||
|
*
|
||||||
|
* @param parent the parent path
|
||||||
|
* @param child the child, must not contain the file separator
|
||||||
|
*/
|
||||||
|
public TokenizedPath(TokenizedPath parent, String child) {
|
||||||
|
if (parent.path.length() > 0
|
||||||
|
&& parent.path.charAt(parent.path.length() - 1)
|
||||||
|
!= File.separatorChar) {
|
||||||
|
path = parent.path + File.separatorChar + child;
|
||||||
|
} else {
|
||||||
|
path = parent.path + child;
|
||||||
|
}
|
||||||
|
tokenizedPath = new String[parent.tokenizedPath.length + 1];
|
||||||
|
System.arraycopy(parent.tokenizedPath, 0, tokenizedPath, 0,
|
||||||
|
parent.tokenizedPath.length);
|
||||||
|
tokenizedPath[parent.tokenizedPath.length] = child;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* package */ TokenizedPath(String path, String[] tokens) {
|
||||||
|
this.path = path;
|
||||||
|
this.tokenizedPath = tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The original path String
|
||||||
|
*/
|
||||||
|
public String toString() {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The depth (or length) of a path.
|
||||||
|
*/
|
||||||
|
public int depth() {
|
||||||
|
return tokenizedPath.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* package */ String[] getTokens() {
|
||||||
|
return tokenizedPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* From <code>base</code> traverse the filesystem in order to find
|
||||||
|
* a file that matches the given name.
|
||||||
|
*
|
||||||
|
* @param base base File (dir).
|
||||||
|
* @param cs whether to scan case-sensitively.
|
||||||
|
* @return File object that points to the file in question or null.
|
||||||
|
*/
|
||||||
|
public File findFile(File base, final boolean cs) {
|
||||||
|
String[] tokens = tokenizedPath;
|
||||||
|
if (FileUtils.isAbsolutePath(path)) {
|
||||||
|
if (base == null) {
|
||||||
|
String[] s = FILE_UTILS.dissect(path);
|
||||||
|
base = new File(s[0]);
|
||||||
|
tokens = SelectorUtils.tokenizePathAsArray(s[1]);
|
||||||
|
} else {
|
||||||
|
File f = FILE_UTILS.normalize(path);
|
||||||
|
String s = FILE_UTILS.removeLeadingPath(base, f);
|
||||||
|
if (s.equals(f.getAbsolutePath())) {
|
||||||
|
//removing base from path yields no change; path
|
||||||
|
//not child of base
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
tokens = SelectorUtils.tokenizePathAsArray(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return findFile(base, tokens, cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do we have to traverse a symlink when trying to reach path from
|
||||||
|
* basedir?
|
||||||
|
* @param base base File (dir).
|
||||||
|
*/
|
||||||
|
public boolean isSymlink(File base) {
|
||||||
|
for (int i = 0; i < tokenizedPath.length; i++) {
|
||||||
|
try {
|
||||||
|
if ((base != null
|
||||||
|
&& SYMLINK_UTILS.isSymbolicLink(base, tokenizedPath[i]))
|
||||||
|
||
|
||||||
|
(base == null
|
||||||
|
&& SYMLINK_UTILS.isSymbolicLink(tokenizedPath[i]))
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
base = new File(base, tokenizedPath[i]);
|
||||||
|
} catch (java.io.IOException ioe) {
|
||||||
|
String msg = "IOException caught while checking "
|
||||||
|
+ "for links, couldn't get canonical path!";
|
||||||
|
// will be caught and redirected to Ant's logging system
|
||||||
|
System.err.println(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* true if the original paths are equal.
|
||||||
|
*/
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
return o instanceof TokenizedPath
|
||||||
|
&& path.equals(((TokenizedPath) o).path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
return path.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* From <code>base</code> traverse the filesystem in order to find
|
||||||
|
* a file that matches the given stack of names.
|
||||||
|
*
|
||||||
|
* @param base base File (dir) - must not be null.
|
||||||
|
* @param pathElements array of path elements (dirs...file).
|
||||||
|
* @param cs whether to scan case-sensitively.
|
||||||
|
* @return File object that points to the file in question or null.
|
||||||
|
*/
|
||||||
|
private static File findFile(File base, final String[] pathElements,
|
||||||
|
final boolean cs) {
|
||||||
|
for (int current = 0; current < pathElements.length; current++) {
|
||||||
|
if (!base.isDirectory()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String[] files = base.list();
|
||||||
|
if (files == null) {
|
||||||
|
throw new BuildException("IO error scanning directory "
|
||||||
|
+ base.getAbsolutePath());
|
||||||
|
}
|
||||||
|
boolean found = false;
|
||||||
|
boolean[] matchCase = cs ? CS_SCAN_ONLY : CS_THEN_NON_CS;
|
||||||
|
for (int i = 0; !found && i < matchCase.length; i++) {
|
||||||
|
for (int j = 0; !found && j < files.length; j++) {
|
||||||
|
if (matchCase[i]
|
||||||
|
? files[j].equals(pathElements[current])
|
||||||
|
: files[j].equalsIgnoreCase(pathElements[current])) {
|
||||||
|
base = new File(base, files[j]);
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pathElements.length == 0 && !base.isDirectory() ? null : base;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a TokenizedPattern from the same tokens that make up
|
||||||
|
* this path.
|
||||||
|
*/
|
||||||
|
public TokenizedPattern toPattern() {
|
||||||
|
return new TokenizedPattern(path, tokenizedPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,177 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.types.selectors;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides reusable path pattern matching. PathPattern is preferable
|
||||||
|
* to equivalent SelectorUtils methods if you need to execute multiple
|
||||||
|
* matching with the same pattern because here the pattern itself will
|
||||||
|
* be parsed only once.
|
||||||
|
* @see SelectorUtils#matchPath(String, String)
|
||||||
|
* @see SelectorUtils#matchPath(String, String, boolean)
|
||||||
|
* @since 1.8.0
|
||||||
|
*/
|
||||||
|
public class TokenizedPattern {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instance that holds no tokens at all.
|
||||||
|
*/
|
||||||
|
public static final TokenizedPattern EMPTY_PATTERN =
|
||||||
|
new TokenizedPattern("", new String[0]);
|
||||||
|
|
||||||
|
private final String pattern;
|
||||||
|
private final String[] tokenizedPattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the PathPattern by parsing it.
|
||||||
|
* @param pattern The pattern to match against. Must not be
|
||||||
|
* <code>null</code>.
|
||||||
|
*/
|
||||||
|
public TokenizedPattern(String pattern) {
|
||||||
|
this(pattern, SelectorUtils.tokenizePathAsArray(pattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
TokenizedPattern(String pattern, String[] tokens) {
|
||||||
|
this.pattern = pattern;
|
||||||
|
this.tokenizedPattern = tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests whether or not a given path matches a given pattern.
|
||||||
|
*
|
||||||
|
* @param path The path to match, as a String. Must not be
|
||||||
|
* <code>null</code>.
|
||||||
|
* @param isCaseSensitive Whether or not matching should be performed
|
||||||
|
* case sensitively.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if the pattern matches against the string,
|
||||||
|
* or <code>false</code> otherwise.
|
||||||
|
*/
|
||||||
|
public boolean matchPath(TokenizedPath path, boolean isCaseSensitive) {
|
||||||
|
return SelectorUtils.matchPath(tokenizedPattern, path.getTokens(),
|
||||||
|
isCaseSensitive);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests whether or not this pattern matches the start of
|
||||||
|
* a path.
|
||||||
|
*/
|
||||||
|
public boolean matchStartOf(TokenizedPath path,
|
||||||
|
boolean caseSensitive) {
|
||||||
|
return SelectorUtils.matchPatternStart(tokenizedPattern,
|
||||||
|
path.getTokens(), caseSensitive);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The pattern String
|
||||||
|
*/
|
||||||
|
public String toString() {
|
||||||
|
return pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPattern() {
|
||||||
|
return pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* true if the original patterns are equal.
|
||||||
|
*/
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
return o instanceof TokenizedPattern
|
||||||
|
&& pattern.equals(((TokenizedPattern) o).pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
return pattern.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The depth (or length) of a pattern.
|
||||||
|
*/
|
||||||
|
public int depth() {
|
||||||
|
return tokenizedPattern.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does the tokenized pattern contain the given string?
|
||||||
|
*/
|
||||||
|
public boolean containsPattern(String pat) {
|
||||||
|
for (int i = 0; i < tokenizedPattern.length; i++) {
|
||||||
|
if (tokenizedPattern[i].equals(pat)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new TokenizedPath where all tokens of this pattern to
|
||||||
|
* the right containing wildcards have been removed
|
||||||
|
* @return the leftmost part of the pattern without wildcards
|
||||||
|
*/
|
||||||
|
public TokenizedPath rtrimWildcardTokens() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
int newLen = 0;
|
||||||
|
for (; newLen < tokenizedPattern.length; newLen++) {
|
||||||
|
if (SelectorUtils.hasWildcards(tokenizedPattern[newLen])) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (newLen > 0
|
||||||
|
&& sb.charAt(sb.length() - 1) != File.separatorChar) {
|
||||||
|
sb.append(File.separator);
|
||||||
|
}
|
||||||
|
sb.append(tokenizedPattern[newLen]);
|
||||||
|
}
|
||||||
|
if (newLen == 0) {
|
||||||
|
return TokenizedPath.EMPTY_PATH;
|
||||||
|
}
|
||||||
|
String[] newPats = new String[newLen];
|
||||||
|
System.arraycopy(tokenizedPattern, 0, newPats, 0, newLen);
|
||||||
|
return new TokenizedPath(sb.toString(), newPats);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* true if the last token equals the given string.
|
||||||
|
*/
|
||||||
|
public boolean endsWith(String s) {
|
||||||
|
return tokenizedPattern.length > 0
|
||||||
|
&& tokenizedPattern[tokenizedPattern.length - 1].equals(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new pattern without the last token of this pattern.
|
||||||
|
*/
|
||||||
|
public TokenizedPattern withoutLastToken() {
|
||||||
|
if (tokenizedPattern.length == 0) {
|
||||||
|
throw new IllegalStateException("cant strip a token from nothing");
|
||||||
|
} else if (tokenizedPattern.length == 1) {
|
||||||
|
return EMPTY_PATTERN;
|
||||||
|
} else {
|
||||||
|
String toStrip = tokenizedPattern[tokenizedPattern.length - 1];
|
||||||
|
int index = pattern.lastIndexOf(toStrip);
|
||||||
|
String[] tokens = new String[tokenizedPattern.length - 1];
|
||||||
|
System.arraycopy(tokenizedPattern, 0, tokens, 0,
|
||||||
|
tokenizedPattern.length - 1);
|
||||||
|
return new TokenizedPattern(pattern.substring(0, index), tokens);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* <html>
|
||||||
|
* <head>
|
||||||
|
* <title>org.owasp.dependencycheck.org.apache.tools.ant.types.selectors</title>
|
||||||
|
* </head>
|
||||||
|
* <body>
|
||||||
|
* This is a copy of classes within Apache Ant. The DirectoryScanner
|
||||||
|
* is needed by dependency-check. However, we did not want to make
|
||||||
|
* Ant a dependency. As such, a few files were copied and slightly
|
||||||
|
* modified to remove any references to the Ant Project class.
|
||||||
|
* </body>
|
||||||
|
* </html>
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.types.selectors;
|
||||||
@@ -0,0 +1,265 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.util;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Dictionary;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
// CheckStyle:HideUtilityClassConstructorCheck OFF - bc
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A set of helper methods related to collection manipulation.
|
||||||
|
*
|
||||||
|
* @since Ant 1.5
|
||||||
|
*/
|
||||||
|
public class CollectionUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collections.emptyList() is Java5+.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
@Deprecated
|
||||||
|
public static final List EMPTY_LIST = Collections.EMPTY_LIST;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Please use Vector.equals() or List.equals().
|
||||||
|
* @param v1 the first vector.
|
||||||
|
* @param v2 the second vector.
|
||||||
|
* @return true if the vectors are equal.
|
||||||
|
* @since Ant 1.5
|
||||||
|
* @deprecated since 1.6.x.
|
||||||
|
*/
|
||||||
|
public static boolean equals(Vector<?> v1, Vector<?> v2) {
|
||||||
|
if (v1 == v2) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v1 == null || v2 == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return v1.equals(v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dictionary does not have an equals.
|
||||||
|
* Please use Map.equals().
|
||||||
|
*
|
||||||
|
* <p>Follows the equals contract of Java 2's Map.</p>
|
||||||
|
* @param d1 the first directory.
|
||||||
|
* @param d2 the second directory.
|
||||||
|
* @return true if the directories are equal.
|
||||||
|
* @since Ant 1.5
|
||||||
|
* @deprecated since 1.6.x.
|
||||||
|
*/
|
||||||
|
public static boolean equals(Dictionary<?, ?> d1, Dictionary<?, ?> d2) {
|
||||||
|
if (d1 == d2) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d1 == null || d2 == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d1.size() != d2.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Enumeration<?> e1 = d1.keys();
|
||||||
|
while (e1.hasMoreElements()) {
|
||||||
|
Object key = e1.nextElement();
|
||||||
|
Object value1 = d1.get(key);
|
||||||
|
Object value2 = d2.get(key);
|
||||||
|
if (value2 == null || !value1.equals(value2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't need the opposite check as the Dictionaries have the
|
||||||
|
// same size, so we've also covered all keys of d2 already.
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a comma separated list of all values held in the given
|
||||||
|
* collection.
|
||||||
|
*
|
||||||
|
* @since Ant 1.8.0
|
||||||
|
*/
|
||||||
|
public static String flattenToString(Collection<?> c) {
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
for (Object o : c) {
|
||||||
|
if (sb.length() != 0) {
|
||||||
|
sb.append(",");
|
||||||
|
}
|
||||||
|
sb.append(o);
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dictionary does not know the putAll method. Please use Map.putAll().
|
||||||
|
* @param m1 the to directory.
|
||||||
|
* @param m2 the from directory.
|
||||||
|
* @since Ant 1.6
|
||||||
|
* @deprecated since 1.6.x.
|
||||||
|
*/
|
||||||
|
public static <K, V> void putAll(Dictionary<? super K, ? super V> m1, Dictionary<? extends K, ? extends V> m2) {
|
||||||
|
for (Enumeration<? extends K> it = m2.keys(); it.hasMoreElements();) {
|
||||||
|
K key = it.nextElement();
|
||||||
|
m1.put(key, m2.get(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An empty enumeration.
|
||||||
|
* @since Ant 1.6
|
||||||
|
*/
|
||||||
|
public static final class EmptyEnumeration<E> implements Enumeration<E> {
|
||||||
|
/** Constructor for the EmptyEnumeration */
|
||||||
|
public EmptyEnumeration() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return false always.
|
||||||
|
*/
|
||||||
|
public boolean hasMoreElements() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return nothing.
|
||||||
|
* @throws NoSuchElementException always.
|
||||||
|
*/
|
||||||
|
public E nextElement() throws NoSuchElementException {
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append one enumeration to another.
|
||||||
|
* Elements are evaluated lazily.
|
||||||
|
* @param e1 the first enumeration.
|
||||||
|
* @param e2 the subsequent enumeration.
|
||||||
|
* @return an enumeration representing e1 followed by e2.
|
||||||
|
* @since Ant 1.6.3
|
||||||
|
*/
|
||||||
|
public static <E> Enumeration<E> append(Enumeration<E> e1, Enumeration<E> e2) {
|
||||||
|
return new CompoundEnumeration<E>(e1, e2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adapt the specified Iterator to the Enumeration interface.
|
||||||
|
* @param iter the Iterator to adapt.
|
||||||
|
* @return an Enumeration.
|
||||||
|
*/
|
||||||
|
public static <E> Enumeration<E> asEnumeration(final Iterator<E> iter) {
|
||||||
|
return new Enumeration<E>() {
|
||||||
|
public boolean hasMoreElements() {
|
||||||
|
return iter.hasNext();
|
||||||
|
}
|
||||||
|
public E nextElement() {
|
||||||
|
return iter.next();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adapt the specified Enumeration to the Iterator interface.
|
||||||
|
* @param e the Enumeration to adapt.
|
||||||
|
* @return an Iterator.
|
||||||
|
*/
|
||||||
|
public static <E> Iterator<E> asIterator(final Enumeration<E> e) {
|
||||||
|
return new Iterator<E>() {
|
||||||
|
public boolean hasNext() {
|
||||||
|
return e.hasMoreElements();
|
||||||
|
}
|
||||||
|
public E next() {
|
||||||
|
return e.nextElement();
|
||||||
|
}
|
||||||
|
public void remove() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a collection containing all elements of the iterator.
|
||||||
|
*
|
||||||
|
* @since Ant 1.8.0
|
||||||
|
*/
|
||||||
|
public static <T> Collection<T> asCollection(final Iterator<? extends T> iter) {
|
||||||
|
List<T> l = new ArrayList<T>();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
l.add(iter.next());
|
||||||
|
}
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class CompoundEnumeration<E> implements Enumeration<E> {
|
||||||
|
|
||||||
|
private final Enumeration<E> e1, e2;
|
||||||
|
|
||||||
|
public CompoundEnumeration(Enumeration<E> e1, Enumeration<E> e2) {
|
||||||
|
this.e1 = e1;
|
||||||
|
this.e2 = e2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasMoreElements() {
|
||||||
|
return e1.hasMoreElements() || e2.hasMoreElements();
|
||||||
|
}
|
||||||
|
|
||||||
|
public E nextElement() throws NoSuchElementException {
|
||||||
|
if (e1.hasMoreElements()) {
|
||||||
|
return e1.nextElement();
|
||||||
|
} else {
|
||||||
|
return e2.nextElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Counts how often the given Object occurs in the given
|
||||||
|
* collection using equals() for comparison.
|
||||||
|
*
|
||||||
|
* @since Ant 1.8.0
|
||||||
|
*/
|
||||||
|
public static int frequency(Collection<?> c, Object o) {
|
||||||
|
// same as Collections.frequency introduced with JDK 1.5
|
||||||
|
int freq = 0;
|
||||||
|
if (c != null) {
|
||||||
|
for (Iterator<?> i = c.iterator(); i.hasNext(); ) {
|
||||||
|
Object test = i.next();
|
||||||
|
if (o == null ? test == null : o.equals(test)) {
|
||||||
|
freq++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,291 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.util;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FilenameFilter;
|
||||||
|
import java.io.IOException;
|
||||||
|
//import org.apache.tools.ant.Task;
|
||||||
|
//import org.apache.tools.ant.taskdefs.Execute;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains methods related to symbolic links - or what Ant thinks is a symbolic link based on the absent support for
|
||||||
|
* them in Java.
|
||||||
|
*
|
||||||
|
* @since Ant 1.8.0
|
||||||
|
*/
|
||||||
|
public class SymbolicLinkUtils {
|
||||||
|
|
||||||
|
private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shared instance.
|
||||||
|
*/
|
||||||
|
private static final SymbolicLinkUtils PRIMARY_INSTANCE
|
||||||
|
= new SymbolicLinkUtils();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to retrieve The SymbolicLinkUtils, which is shared by all users of this method.
|
||||||
|
*
|
||||||
|
* @return an instance of SymbolicLinkUtils.
|
||||||
|
*/
|
||||||
|
public static SymbolicLinkUtils getSymbolicLinkUtils() {
|
||||||
|
// keep the door open for Java X.Y specific subclass if symbolic
|
||||||
|
// links ever become supported in the classlib
|
||||||
|
return PRIMARY_INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty constructor.
|
||||||
|
*/
|
||||||
|
protected SymbolicLinkUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a given file is a symbolic link.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* It doesn't really test for symbolic links but whether the canonical and absolute paths of the file are
|
||||||
|
* identical--this may lead to false positives on some platforms.</p>
|
||||||
|
*
|
||||||
|
* @param file the file to test. Must not be null.
|
||||||
|
*
|
||||||
|
* @return true if the file is a symbolic link.
|
||||||
|
* @throws IOException on error.
|
||||||
|
*/
|
||||||
|
public boolean isSymbolicLink(File file) throws IOException {
|
||||||
|
return isSymbolicLink(file.getParentFile(), file.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a given file is a symbolic link.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* It doesn't really test for symbolic links but whether the canonical and absolute paths of the file are
|
||||||
|
* identical--this may lead to false positives on some platforms.</p>
|
||||||
|
*
|
||||||
|
* @param name the name of the file to test.
|
||||||
|
*
|
||||||
|
* @return true if the file is a symbolic link.
|
||||||
|
* @throws IOException on error.
|
||||||
|
*/
|
||||||
|
public boolean isSymbolicLink(String name) throws IOException {
|
||||||
|
return isSymbolicLink(new File(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a given file is a symbolic link.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* It doesn't really test for symbolic links but whether the canonical and absolute paths of the file are
|
||||||
|
* identical--this may lead to false positives on some platforms.</p>
|
||||||
|
*
|
||||||
|
* @param parent the parent directory of the file to test
|
||||||
|
* @param name the name of the file to test.
|
||||||
|
*
|
||||||
|
* @return true if the file is a symbolic link.
|
||||||
|
* @throws IOException on error.
|
||||||
|
*/
|
||||||
|
public boolean isSymbolicLink(File parent, String name)
|
||||||
|
throws IOException {
|
||||||
|
File toTest = parent != null
|
||||||
|
? new File(parent.getCanonicalPath(), name)
|
||||||
|
: new File(name);
|
||||||
|
return !toTest.getAbsolutePath().equals(toTest.getCanonicalPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a given file is a broken symbolic link.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* It doesn't really test for symbolic links but whether Java reports that the File doesn't exist but its parent's
|
||||||
|
* child list contains it--this may lead to false positives on some platforms.</p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Note that #isSymbolicLink returns false if this method returns true since Java won't produce a canonical name
|
||||||
|
* different from the abolute one if the link is broken.</p>
|
||||||
|
*
|
||||||
|
* @param name the name of the file to test.
|
||||||
|
*
|
||||||
|
* @return true if the file is a broken symbolic link.
|
||||||
|
* @throws IOException on error.
|
||||||
|
*/
|
||||||
|
public boolean isDanglingSymbolicLink(String name) throws IOException {
|
||||||
|
return isDanglingSymbolicLink(new File(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a given file is a broken symbolic link.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* It doesn't really test for symbolic links but whether Java reports that the File doesn't exist but its parent's
|
||||||
|
* child list contains it--this may lead to false positives on some platforms.</p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Note that #isSymbolicLink returns false if this method returns true since Java won't produce a canonical name
|
||||||
|
* different from the abolute one if the link is broken.</p>
|
||||||
|
*
|
||||||
|
* @param file the file to test.
|
||||||
|
*
|
||||||
|
* @return true if the file is a broken symbolic link.
|
||||||
|
* @throws IOException on error.
|
||||||
|
*/
|
||||||
|
public boolean isDanglingSymbolicLink(File file) throws IOException {
|
||||||
|
return isDanglingSymbolicLink(file.getParentFile(), file.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a given file is a broken symbolic link.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* It doesn't really test for symbolic links but whether Java reports that the File doesn't exist but its parent's
|
||||||
|
* child list contains it--this may lead to false positives on some platforms.</p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Note that #isSymbolicLink returns false if this method returns true since Java won't produce a canonical name
|
||||||
|
* different from the abolute one if the link is broken.</p>
|
||||||
|
*
|
||||||
|
* @param parent the parent directory of the file to test
|
||||||
|
* @param name the name of the file to test.
|
||||||
|
*
|
||||||
|
* @return true if the file is a broken symbolic link.
|
||||||
|
* @throws IOException on error.
|
||||||
|
*/
|
||||||
|
public boolean isDanglingSymbolicLink(File parent, String name)
|
||||||
|
throws IOException {
|
||||||
|
File f = new File(parent, name);
|
||||||
|
if (!f.exists()) {
|
||||||
|
final String localName = f.getName();
|
||||||
|
String[] c = parent.list(new FilenameFilter() {
|
||||||
|
public boolean accept(File d, String n) {
|
||||||
|
return localName.equals(n);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return c != null && c.length > 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Delete a symlink (without deleting the associated resource).
|
||||||
|
// *
|
||||||
|
// * <p>This is a utility method that removes a unix symlink without
|
||||||
|
// * removing the resource that the symlink points to. If it is
|
||||||
|
// * accidentally invoked on a real file, the real file will not be
|
||||||
|
// * harmed, but silently ignored.</p>
|
||||||
|
// *
|
||||||
|
// * <p>Normally this method works by
|
||||||
|
// * getting the canonical path of the link, using the canonical path to
|
||||||
|
// * rename the resource (breaking the link) and then deleting the link.
|
||||||
|
// * The resource is then returned to its original name inside a finally
|
||||||
|
// * block to ensure that the resource is unharmed even in the event of
|
||||||
|
// * an exception.</p>
|
||||||
|
// *
|
||||||
|
// * <p>There may be cases where the algorithm described above doesn't work,
|
||||||
|
// * in that case the method tries to use the native "rm" command on
|
||||||
|
// * the symlink instead.</p>
|
||||||
|
// *
|
||||||
|
// * @param link A <code>File</code> object of the symlink to delete.
|
||||||
|
// * @param task An Ant Task required if "rm" needs to be invoked.
|
||||||
|
// *
|
||||||
|
// * @throws IOException If calls to <code>File.rename</code>,
|
||||||
|
// * <code>File.delete</code> or <code>File.getCanonicalPath</code>
|
||||||
|
// * fail.
|
||||||
|
// * @throws BuildException if the execution of "rm" failed.
|
||||||
|
// */
|
||||||
|
// public void deleteSymbolicLink(File link, Task task)
|
||||||
|
// throws IOException {
|
||||||
|
// if (isDanglingSymbolicLink(link)) {
|
||||||
|
// if (!link.delete()) {
|
||||||
|
// throw new IOException("failed to remove dangling symbolic link "
|
||||||
|
// + link);
|
||||||
|
// }
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (!isSymbolicLink(link)) {
|
||||||
|
// // plain file, not a link
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (!link.exists()) {
|
||||||
|
// throw new FileNotFoundException("No such symbolic link: " + link);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // find the resource of the existing link:
|
||||||
|
// File target = link.getCanonicalFile();
|
||||||
|
//
|
||||||
|
// // no reason to try the renaming algorithm if we aren't allowed to
|
||||||
|
// // write to the target's parent directory. Let's hope that
|
||||||
|
// // File.canWrite works on all platforms.
|
||||||
|
//
|
||||||
|
// if (task == null || target.getParentFile().canWrite()) {
|
||||||
|
//
|
||||||
|
// // rename the resource, thus breaking the link:
|
||||||
|
// File temp = FILE_UTILS.createTempFile("symlink", ".tmp",
|
||||||
|
// target.getParentFile(), false,
|
||||||
|
// false);
|
||||||
|
//
|
||||||
|
// if (FILE_UTILS.isLeadingPath(target, link)) {
|
||||||
|
// // link points to a parent directory, renaming the parent
|
||||||
|
// // will rename the file
|
||||||
|
// link = new File(temp,
|
||||||
|
// FILE_UTILS.removeLeadingPath(target, link));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// boolean renamedTarget = false;
|
||||||
|
// try {
|
||||||
|
// try {
|
||||||
|
// FILE_UTILS.rename(target, temp);
|
||||||
|
// renamedTarget = true;
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// throw new IOException("Couldn't rename resource when "
|
||||||
|
// + "attempting to delete '" + link
|
||||||
|
// + "'. Reason: " + e.getMessage());
|
||||||
|
// }
|
||||||
|
// // delete the (now) broken link:
|
||||||
|
// if (!link.delete()) {
|
||||||
|
// throw new IOException("Couldn't delete symlink: "
|
||||||
|
// + link
|
||||||
|
// + " (was it a real file? is this "
|
||||||
|
// + "not a UNIX system?)");
|
||||||
|
// }
|
||||||
|
// } finally {
|
||||||
|
// if (renamedTarget) {
|
||||||
|
// // return the resource to its original name:
|
||||||
|
// try {
|
||||||
|
// FILE_UTILS.rename(temp, target);
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// throw new IOException("Couldn't return resource "
|
||||||
|
// + temp
|
||||||
|
// + " to its original name: "
|
||||||
|
// + target.getAbsolutePath()
|
||||||
|
// + ". Reason: " + e.getMessage()
|
||||||
|
// + "\n THE RESOURCE'S NAME ON DISK"
|
||||||
|
// + " HAS BEEN CHANGED BY THIS"
|
||||||
|
// + " ERROR!\n");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// Execute.runCommand(task,
|
||||||
|
// new String[] {"rm", link.getAbsolutePath()});
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,242 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.util;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subclass of Vector that won't store duplicate entries and shows
|
||||||
|
* HashSet's constant time performance characteristics for the
|
||||||
|
* contains method.
|
||||||
|
*
|
||||||
|
* <p>This is not a general purpose class but has been written because
|
||||||
|
* the protected members of {@link
|
||||||
|
* org.apache.tools.ant.DirectoryScanner DirectoryScanner} prohibited
|
||||||
|
* later revisions from using a more efficient collection.</p>
|
||||||
|
*
|
||||||
|
* <p>Methods are synchronized to keep Vector's contract.</p>
|
||||||
|
*
|
||||||
|
* @since Ant 1.8.0
|
||||||
|
*/
|
||||||
|
public final class VectorSet<E> extends Vector<E> {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final HashSet<E> set = new HashSet<E>();
|
||||||
|
|
||||||
|
public VectorSet() { super(); }
|
||||||
|
|
||||||
|
public VectorSet(int initialCapacity) { super(initialCapacity); }
|
||||||
|
|
||||||
|
public VectorSet(int initialCapacity, int capacityIncrement) {
|
||||||
|
super(initialCapacity, capacityIncrement);
|
||||||
|
}
|
||||||
|
|
||||||
|
public VectorSet(Collection<? extends E> c) {
|
||||||
|
if (c != null) {
|
||||||
|
for (E e : c) {
|
||||||
|
add(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized boolean add(E o) {
|
||||||
|
if (!set.contains(o)) {
|
||||||
|
doAdd(size(), o);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This implementation may not add the element at the given index
|
||||||
|
* if it is already contained in the collection.
|
||||||
|
*/
|
||||||
|
public void add(int index, E o) {
|
||||||
|
doAdd(index, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void doAdd(int index, E o) {
|
||||||
|
// Vector.add seems to delegate to insertElementAt, but this
|
||||||
|
// is not documented so we may better implement it ourselves
|
||||||
|
if (set.add(o)) {
|
||||||
|
int count = size();
|
||||||
|
ensureCapacity(count + 1);
|
||||||
|
if (index != count) {
|
||||||
|
System.arraycopy(elementData, index, elementData, index + 1,
|
||||||
|
count - index);
|
||||||
|
}
|
||||||
|
elementData[index] = o;
|
||||||
|
elementCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void addElement(E o) {
|
||||||
|
doAdd(size(), o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized boolean addAll(Collection<? extends E> c) {
|
||||||
|
boolean changed = false;
|
||||||
|
for (E e : c) {
|
||||||
|
changed |= add(e);
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This implementation may not add all elements at the given index
|
||||||
|
* if any of them are already contained in the collection.
|
||||||
|
*/
|
||||||
|
public synchronized boolean addAll(int index, Collection<? extends E> c) {
|
||||||
|
LinkedList toAdd = new LinkedList();
|
||||||
|
for (E e : c) {
|
||||||
|
if (set.add(e)) {
|
||||||
|
toAdd.add(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (toAdd.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int count = size();
|
||||||
|
ensureCapacity(count + toAdd.size());
|
||||||
|
if (index != count) {
|
||||||
|
System.arraycopy(elementData, index, elementData, index + toAdd.size(),
|
||||||
|
count - index);
|
||||||
|
}
|
||||||
|
for (Object o : toAdd) {
|
||||||
|
elementData[index++] = o;
|
||||||
|
}
|
||||||
|
elementCount += toAdd.size();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void clear() {
|
||||||
|
super.clear();
|
||||||
|
set.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object clone() {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final VectorSet<E> vs = (VectorSet<E>) super.clone();
|
||||||
|
vs.set.addAll(set);
|
||||||
|
return vs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized boolean contains(Object o) {
|
||||||
|
return set.contains(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized boolean containsAll(Collection<?> c) {
|
||||||
|
return set.containsAll(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void insertElementAt(E o, int index) {
|
||||||
|
doAdd(index, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized E remove(int index) {
|
||||||
|
E o = get(index);
|
||||||
|
remove(o);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean remove(Object o) {
|
||||||
|
return doRemove(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized boolean doRemove(Object o) {
|
||||||
|
// again, remove seems to delegate to removeElement, but we
|
||||||
|
// shouldn't trust it
|
||||||
|
if (set.remove(o)) {
|
||||||
|
int index = indexOf(o);
|
||||||
|
if (index < elementData.length - 1) {
|
||||||
|
System.arraycopy(elementData, index + 1, elementData, index,
|
||||||
|
elementData.length - index - 1);
|
||||||
|
}
|
||||||
|
elementCount--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized boolean removeAll(Collection<?> c) {
|
||||||
|
boolean changed = false;
|
||||||
|
for (Object o : c) {
|
||||||
|
changed |= remove(o);
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void removeAllElements() {
|
||||||
|
set.clear();
|
||||||
|
super.removeAllElements();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean removeElement(Object o) {
|
||||||
|
return doRemove(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void removeElementAt(int index) {
|
||||||
|
remove(get(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void removeRange(final int fromIndex, int toIndex) {
|
||||||
|
while (toIndex > fromIndex) {
|
||||||
|
remove(--toIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized boolean retainAll(Collection<?> c) {
|
||||||
|
if (!(c instanceof Set)) {
|
||||||
|
c = new HashSet<Object>(c);
|
||||||
|
}
|
||||||
|
LinkedList<E> l = new LinkedList<E>();
|
||||||
|
for (E o : this) {
|
||||||
|
if (!c.contains(o)) {
|
||||||
|
l.addLast(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!l.isEmpty()) {
|
||||||
|
removeAll(l);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized E set(int index, E o) {
|
||||||
|
E orig = get(index);
|
||||||
|
if (set.add(o)) {
|
||||||
|
elementData[index] = o;
|
||||||
|
set.remove(orig);
|
||||||
|
} else {
|
||||||
|
int oldIndexOfO = indexOf(o);
|
||||||
|
remove(o);
|
||||||
|
remove(orig);
|
||||||
|
add(oldIndexOfO > index ? index : index - 1, o);
|
||||||
|
}
|
||||||
|
return orig;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setElementAt(E o, int index) {
|
||||||
|
set(index, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* <html>
|
||||||
|
* <head>
|
||||||
|
* <title>org.owasp.dependencycheck.org.apache.tools.ant.util</title>
|
||||||
|
* </head>
|
||||||
|
* <body>
|
||||||
|
* This is a copy of classes within Apache Ant. The DirectoryScanner
|
||||||
|
* is needed by dependency-check. However, we did not want to make
|
||||||
|
* Ant a dependency. As such, a few files were copied and slightly
|
||||||
|
* modified to remove any references to the Ant Project class.
|
||||||
|
* </body>
|
||||||
|
* </html>
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant.util;
|
||||||
@@ -78,7 +78,7 @@ public final class FileUtils {
|
|||||||
if (!org.apache.commons.io.FileUtils.deleteQuietly(file)) {
|
if (!org.apache.commons.io.FileUtils.deleteQuietly(file)) {
|
||||||
success = false;
|
success = false;
|
||||||
final String msg = String.format("Failed to delete file: %s; attempting to delete on exit.", file.getPath());
|
final String msg = String.format("Failed to delete file: %s; attempting to delete on exit.", file.getPath());
|
||||||
LOGGER.log(Level.FINE, msg);
|
LOGGER.log(Level.INFO, msg);
|
||||||
file.deleteOnExit();
|
file.deleteOnExit();
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
|
|||||||
@@ -188,6 +188,14 @@ public final class Settings {
|
|||||||
* The properties key for using the proxy to reach Nexus.
|
* The properties key for using the proxy to reach Nexus.
|
||||||
*/
|
*/
|
||||||
public static final String ANALYZER_NEXUS_PROXY = "analyzer.nexus.proxy";
|
public static final String ANALYZER_NEXUS_PROXY = "analyzer.nexus.proxy";
|
||||||
|
/**
|
||||||
|
* The properties key for whether the Central analyzer is enabled.
|
||||||
|
*/
|
||||||
|
public static final String ANALYZER_CENTRAL_ENABLED = "analyzer.central.enabled";
|
||||||
|
/**
|
||||||
|
* The properties key for the Central search URL.
|
||||||
|
*/
|
||||||
|
public static final String ANALYZER_CENTRAL_URL = "analyzer.central.url";
|
||||||
/**
|
/**
|
||||||
* The path to mono, if available.
|
* The path to mono, if available.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,732 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 OWASP.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.org.apache.tools.ant;
|
||||||
|
|
||||||
|
import org.owasp.dependencycheck.org.apache.tools.ant.DirectoryScanner;
|
||||||
|
import java.io.File;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||||
|
*/
|
||||||
|
public class DirectoryScannerTest {
|
||||||
|
|
||||||
|
public DirectoryScannerTest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpClass() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void tearDownClass() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testing the expected use of the directory scanner.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testExpectedUse() {
|
||||||
|
DirectoryScanner scanner = new DirectoryScanner();
|
||||||
|
scanner.setBasedir("./target");
|
||||||
|
scanner.setIncludes("/test-classes/**");
|
||||||
|
scanner.scan();
|
||||||
|
|
||||||
|
File base = new File("./target");
|
||||||
|
for (String t : scanner.getIncludedFiles()) {
|
||||||
|
assertTrue(t.startsWith("test-classes"));
|
||||||
|
File test = new File(base, t);
|
||||||
|
assertTrue(test.exists());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test of matchPatternStart method, of class DirectoryScanner.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testMatchPatternStart_String_String() {
|
||||||
|
String pattern = "alpha/be?a/**";
|
||||||
|
String str = "alpha/beta/gamma/";
|
||||||
|
boolean expResult = true;
|
||||||
|
boolean result = DirectoryScanner.matchPatternStart(pattern, str);
|
||||||
|
assertEquals(expResult, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test of matchPatternStart method, of class DirectoryScanner.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testMatchPatternStart_3args() {
|
||||||
|
String pattern = "Alpha/be?a/**";
|
||||||
|
String str = "alpha/beta/gamma/";
|
||||||
|
boolean isCaseSensitive = true;
|
||||||
|
boolean expResult = false;
|
||||||
|
boolean result = DirectoryScanner.matchPatternStart(pattern, str, isCaseSensitive);
|
||||||
|
assertEquals(expResult, result);
|
||||||
|
|
||||||
|
isCaseSensitive = false;
|
||||||
|
expResult = true;
|
||||||
|
result = DirectoryScanner.matchPatternStart(pattern, str, isCaseSensitive);
|
||||||
|
assertEquals(expResult, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test of matchPath method, of class DirectoryScanner.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testMatchPath_String_String() {
|
||||||
|
String pattern = "alpha/be?a/**";
|
||||||
|
String str = "alpha/beta/gamma/";
|
||||||
|
boolean expResult = true;
|
||||||
|
boolean result = DirectoryScanner.matchPath(pattern, str);
|
||||||
|
assertEquals(expResult, result);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of matchPath method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testMatchPath_3args() {
|
||||||
|
// System.out.println("matchPath");
|
||||||
|
// String pattern = "";
|
||||||
|
// String str = "";
|
||||||
|
// boolean isCaseSensitive = false;
|
||||||
|
// boolean expResult = false;
|
||||||
|
// boolean result = DirectoryScanner.matchPath(pattern, str, isCaseSensitive);
|
||||||
|
// assertEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of match method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testMatch_String_String() {
|
||||||
|
// System.out.println("match");
|
||||||
|
// String pattern = "";
|
||||||
|
// String str = "";
|
||||||
|
// boolean expResult = false;
|
||||||
|
// boolean result = DirectoryScanner.match(pattern, str);
|
||||||
|
// assertEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of match method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testMatch_3args() {
|
||||||
|
// System.out.println("match");
|
||||||
|
// String pattern = "";
|
||||||
|
// String str = "";
|
||||||
|
// boolean isCaseSensitive = false;
|
||||||
|
// boolean expResult = false;
|
||||||
|
// boolean result = DirectoryScanner.match(pattern, str, isCaseSensitive);
|
||||||
|
// assertEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of getDefaultExcludes method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testGetDefaultExcludes() {
|
||||||
|
// System.out.println("getDefaultExcludes");
|
||||||
|
// String[] expResult = null;
|
||||||
|
// String[] result = DirectoryScanner.getDefaultExcludes();
|
||||||
|
// assertArrayEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of addDefaultExclude method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testAddDefaultExclude() {
|
||||||
|
// System.out.println("addDefaultExclude");
|
||||||
|
// String s = "";
|
||||||
|
// boolean expResult = false;
|
||||||
|
// boolean result = DirectoryScanner.addDefaultExclude(s);
|
||||||
|
// assertEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of removeDefaultExclude method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testRemoveDefaultExclude() {
|
||||||
|
// System.out.println("removeDefaultExclude");
|
||||||
|
// String s = "";
|
||||||
|
// boolean expResult = false;
|
||||||
|
// boolean result = DirectoryScanner.removeDefaultExclude(s);
|
||||||
|
// assertEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of resetDefaultExcludes method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testResetDefaultExcludes() {
|
||||||
|
// System.out.println("resetDefaultExcludes");
|
||||||
|
// DirectoryScanner.resetDefaultExcludes();
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of setBasedir method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testSetBasedir_String() {
|
||||||
|
// System.out.println("setBasedir");
|
||||||
|
// String basedir = "";
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// instance.setBasedir(basedir);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of setBasedir method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testSetBasedir_File() {
|
||||||
|
// System.out.println("setBasedir");
|
||||||
|
// File basedir = null;
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// instance.setBasedir(basedir);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of getBasedir method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testGetBasedir() {
|
||||||
|
// System.out.println("getBasedir");
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// File expResult = null;
|
||||||
|
// File result = instance.getBasedir();
|
||||||
|
// assertEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of isCaseSensitive method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testIsCaseSensitive() {
|
||||||
|
// System.out.println("isCaseSensitive");
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// boolean expResult = false;
|
||||||
|
// boolean result = instance.isCaseSensitive();
|
||||||
|
// assertEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of setCaseSensitive method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testSetCaseSensitive() {
|
||||||
|
// System.out.println("setCaseSensitive");
|
||||||
|
// boolean isCaseSensitive = false;
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// instance.setCaseSensitive(isCaseSensitive);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of setErrorOnMissingDir method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testSetErrorOnMissingDir() {
|
||||||
|
// System.out.println("setErrorOnMissingDir");
|
||||||
|
// boolean errorOnMissingDir = false;
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// instance.setErrorOnMissingDir(errorOnMissingDir);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of isFollowSymlinks method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testIsFollowSymlinks() {
|
||||||
|
// System.out.println("isFollowSymlinks");
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// boolean expResult = false;
|
||||||
|
// boolean result = instance.isFollowSymlinks();
|
||||||
|
// assertEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of setFollowSymlinks method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testSetFollowSymlinks() {
|
||||||
|
// System.out.println("setFollowSymlinks");
|
||||||
|
// boolean followSymlinks = false;
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// instance.setFollowSymlinks(followSymlinks);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of setMaxLevelsOfSymlinks method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testSetMaxLevelsOfSymlinks() {
|
||||||
|
// System.out.println("setMaxLevelsOfSymlinks");
|
||||||
|
// int max = 0;
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// instance.setMaxLevelsOfSymlinks(max);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of setIncludes method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testSetIncludes() {
|
||||||
|
// System.out.println("setIncludes");
|
||||||
|
// String[] includes = null;
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// instance.setIncludes(includes);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of setExcludes method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testSetExcludes() {
|
||||||
|
// System.out.println("setExcludes");
|
||||||
|
// String[] excludes = null;
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// instance.setExcludes(excludes);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of addExcludes method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testAddExcludes() {
|
||||||
|
// System.out.println("addExcludes");
|
||||||
|
// String[] excludes = null;
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// instance.addExcludes(excludes);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of setSelectors method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testSetSelectors() {
|
||||||
|
// System.out.println("setSelectors");
|
||||||
|
// FileSelector[] selectors = null;
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// instance.setSelectors(selectors);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of isEverythingIncluded method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testIsEverythingIncluded() {
|
||||||
|
// System.out.println("isEverythingIncluded");
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// boolean expResult = false;
|
||||||
|
// boolean result = instance.isEverythingIncluded();
|
||||||
|
// assertEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of scan method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testScan() {
|
||||||
|
// System.out.println("scan");
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// instance.scan();
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of clearResults method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testClearResults() {
|
||||||
|
// System.out.println("clearResults");
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// instance.clearResults();
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of slowScan method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testSlowScan() {
|
||||||
|
// System.out.println("slowScan");
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// instance.slowScan();
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of scandir method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testScandir() {
|
||||||
|
// System.out.println("scandir");
|
||||||
|
// File dir = null;
|
||||||
|
// String vpath = "";
|
||||||
|
// boolean fast = false;
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// instance.scandir(dir, vpath, fast);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of isIncluded method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testIsIncluded() {
|
||||||
|
// System.out.println("isIncluded");
|
||||||
|
// String name = "";
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// boolean expResult = false;
|
||||||
|
// boolean result = instance.isIncluded(name);
|
||||||
|
// assertEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of couldHoldIncluded method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testCouldHoldIncluded() {
|
||||||
|
// System.out.println("couldHoldIncluded");
|
||||||
|
// String name = "";
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// boolean expResult = false;
|
||||||
|
// boolean result = instance.couldHoldIncluded(name);
|
||||||
|
// assertEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of contentsExcluded method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testContentsExcluded() {
|
||||||
|
// System.out.println("contentsExcluded");
|
||||||
|
// TokenizedPath path = null;
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// boolean expResult = false;
|
||||||
|
// boolean result = instance.contentsExcluded(path);
|
||||||
|
// assertEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of isExcluded method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testIsExcluded() {
|
||||||
|
// System.out.println("isExcluded");
|
||||||
|
// String name = "";
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// boolean expResult = false;
|
||||||
|
// boolean result = instance.isExcluded(name);
|
||||||
|
// assertEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of isSelected method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testIsSelected() {
|
||||||
|
// System.out.println("isSelected");
|
||||||
|
// String name = "";
|
||||||
|
// File file = null;
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// boolean expResult = false;
|
||||||
|
// boolean result = instance.isSelected(name, file);
|
||||||
|
// assertEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of getIncludedFiles method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testGetIncludedFiles() {
|
||||||
|
// System.out.println("getIncludedFiles");
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// String[] expResult = null;
|
||||||
|
// String[] result = instance.getIncludedFiles();
|
||||||
|
// assertArrayEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of getIncludedFilesCount method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testGetIncludedFilesCount() {
|
||||||
|
// System.out.println("getIncludedFilesCount");
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// int expResult = 0;
|
||||||
|
// int result = instance.getIncludedFilesCount();
|
||||||
|
// assertEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of getNotIncludedFiles method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testGetNotIncludedFiles() {
|
||||||
|
// System.out.println("getNotIncludedFiles");
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// String[] expResult = null;
|
||||||
|
// String[] result = instance.getNotIncludedFiles();
|
||||||
|
// assertArrayEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of getExcludedFiles method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testGetExcludedFiles() {
|
||||||
|
// System.out.println("getExcludedFiles");
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// String[] expResult = null;
|
||||||
|
// String[] result = instance.getExcludedFiles();
|
||||||
|
// assertArrayEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of getDeselectedFiles method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testGetDeselectedFiles() {
|
||||||
|
// System.out.println("getDeselectedFiles");
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// String[] expResult = null;
|
||||||
|
// String[] result = instance.getDeselectedFiles();
|
||||||
|
// assertArrayEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of getIncludedDirectories method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testGetIncludedDirectories() {
|
||||||
|
// System.out.println("getIncludedDirectories");
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// String[] expResult = null;
|
||||||
|
// String[] result = instance.getIncludedDirectories();
|
||||||
|
// assertArrayEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of getIncludedDirsCount method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testGetIncludedDirsCount() {
|
||||||
|
// System.out.println("getIncludedDirsCount");
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// int expResult = 0;
|
||||||
|
// int result = instance.getIncludedDirsCount();
|
||||||
|
// assertEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of getNotIncludedDirectories method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testGetNotIncludedDirectories() {
|
||||||
|
// System.out.println("getNotIncludedDirectories");
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// String[] expResult = null;
|
||||||
|
// String[] result = instance.getNotIncludedDirectories();
|
||||||
|
// assertArrayEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of getExcludedDirectories method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testGetExcludedDirectories() {
|
||||||
|
// System.out.println("getExcludedDirectories");
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// String[] expResult = null;
|
||||||
|
// String[] result = instance.getExcludedDirectories();
|
||||||
|
// assertArrayEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of getDeselectedDirectories method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testGetDeselectedDirectories() {
|
||||||
|
// System.out.println("getDeselectedDirectories");
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// String[] expResult = null;
|
||||||
|
// String[] result = instance.getDeselectedDirectories();
|
||||||
|
// assertArrayEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of getNotFollowedSymlinks method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testGetNotFollowedSymlinks() {
|
||||||
|
// System.out.println("getNotFollowedSymlinks");
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// String[] expResult = null;
|
||||||
|
// String[] result = instance.getNotFollowedSymlinks();
|
||||||
|
// assertArrayEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of addDefaultExcludes method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testAddDefaultExcludes() {
|
||||||
|
// System.out.println("addDefaultExcludes");
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// instance.addDefaultExcludes();
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of getResource method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testGetResource() {
|
||||||
|
// System.out.println("getResource");
|
||||||
|
// String name = "";
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// Resource expResult = null;
|
||||||
|
// Resource result = instance.getResource(name);
|
||||||
|
// assertEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of getScannedDirs method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testGetScannedDirs() {
|
||||||
|
// System.out.println("getScannedDirs");
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// Set<String> expResult = null;
|
||||||
|
// Set<String> result = instance.getScannedDirs();
|
||||||
|
// assertEquals(expResult, result);
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test of ensureNonPatternSetsReady method, of class DirectoryScanner.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void testEnsureNonPatternSetsReady() {
|
||||||
|
// System.out.println("ensureNonPatternSetsReady");
|
||||||
|
// DirectoryScanner instance = new DirectoryScanner();
|
||||||
|
// instance.ensureNonPatternSetsReady();
|
||||||
|
// // TODO review the generated test code and remove the default call to fail.
|
||||||
|
// fail("The test case is a prototype.");
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
@@ -20,12 +20,11 @@ package org.owasp.dependencycheck.utils;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.AfterClass;
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Rule;
|
||||||
import org.junit.BeforeClass;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
import org.owasp.dependencycheck.utils.Checksum;
|
import org.owasp.dependencycheck.utils.Checksum;
|
||||||
import org.owasp.dependencycheck.utils.Checksum;
|
import org.owasp.dependencycheck.utils.Checksum;
|
||||||
|
|
||||||
@@ -35,21 +34,8 @@ import org.owasp.dependencycheck.utils.Checksum;
|
|||||||
*/
|
*/
|
||||||
public class ChecksumTest {
|
public class ChecksumTest {
|
||||||
|
|
||||||
@BeforeClass
|
@Rule
|
||||||
public static void setUpClass() throws Exception {
|
public ExpectedException expectedException = ExpectedException.none();
|
||||||
}
|
|
||||||
|
|
||||||
@AfterClass
|
|
||||||
public static void tearDownClass() throws Exception {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown() throws Exception {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test of getChecksum method, of class Checksum.
|
* Test of getChecksum method, of class Checksum.
|
||||||
@@ -83,13 +69,9 @@ public class ChecksumTest {
|
|||||||
public void testGetChecksum_FileNotFound() throws Exception {
|
public void testGetChecksum_FileNotFound() throws Exception {
|
||||||
String algorithm = "MD5";
|
String algorithm = "MD5";
|
||||||
File file = new File("not a valid file");
|
File file = new File("not a valid file");
|
||||||
boolean exceptionThrown = false;
|
|
||||||
try {
|
expectedException.expect(IOException.class);
|
||||||
byte[] result = Checksum.getChecksum(algorithm, file);
|
Checksum.getChecksum(algorithm, file);
|
||||||
} catch (IOException ex) {
|
|
||||||
exceptionThrown = true;
|
|
||||||
}
|
|
||||||
Assert.assertTrue(exceptionThrown);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -102,13 +84,9 @@ public class ChecksumTest {
|
|||||||
public void testGetChecksum_NoSuchAlgorithm() throws Exception {
|
public void testGetChecksum_NoSuchAlgorithm() throws Exception {
|
||||||
String algorithm = "some unknown algorithm";
|
String algorithm = "some unknown algorithm";
|
||||||
File file = new File(this.getClass().getClassLoader().getResource("checkSumTest.file").getPath());
|
File file = new File(this.getClass().getClassLoader().getResource("checkSumTest.file").getPath());
|
||||||
boolean exceptionThrown = false;
|
|
||||||
try {
|
expectedException.expect(NoSuchAlgorithmException.class);
|
||||||
byte[] result = Checksum.getChecksum(algorithm, file);
|
Checksum.getChecksum(algorithm, file);
|
||||||
} catch (NoSuchAlgorithmException ex) {
|
|
||||||
exceptionThrown = true;
|
|
||||||
}
|
|
||||||
Assert.assertTrue(exceptionThrown);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
2
pom.xml
2
pom.xml
@@ -20,7 +20,7 @@ Copyright (c) 2012 - Jeremy Long
|
|||||||
|
|
||||||
<groupId>org.owasp</groupId>
|
<groupId>org.owasp</groupId>
|
||||||
<artifactId>dependency-check-parent</artifactId>
|
<artifactId>dependency-check-parent</artifactId>
|
||||||
<version>1.2.5</version>
|
<version>1.2.6-SNAPSHOT</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
|
|
||||||
<suppressions>
|
<suppressions>
|
||||||
<suppress checks=".*" files=".*[\\/]package-info\.java" />
|
<suppress checks=".*" files=".*[\\/]package-info\.java" />
|
||||||
<suppress checks=".*" files=".*org[\\/]owasp[\\/]dependencycheck[\\/]utils[\\/]Filter.java" />
|
<suppress checks=".*" files=".*[\\/]org[\\/]owasp[\\/]dependencycheck[\\/]utils[\\/]Filter.java" />
|
||||||
<suppress checks=".*" files=".*org[\\/]owasp[\\/]dependencycheck[\\/]utils[\\/]Checksum.java" />
|
<suppress checks=".*" files=".*[\\/]org[\\/]owasp[\\/]dependencycheck[\\/]utils[\\/]Checksum.java" />
|
||||||
<suppress checks=".*" files=".*[\\/]generated[\\/].*.java" />
|
<suppress checks=".*" files=".*[\\/]generated[\\/].*.java" />
|
||||||
|
<suppress checks=".*" files=".*[\\/]org[\\/]owasp[\\/]dependencycheck[\\/]org[\\/]apache[\\/].*.java" />
|
||||||
</suppressions>
|
</suppressions>
|
||||||
@@ -7,7 +7,7 @@ dependent libraries) to identify known vulnerable components.
|
|||||||
|
|
||||||
The problem with using known vulnerable components was covered in a paper by Jeff
|
The problem with using known vulnerable components was covered in a paper by Jeff
|
||||||
Williams and Arshan Dabirsiaghi titled, "[The Unfortunate Reality of Insecure
|
Williams and Arshan Dabirsiaghi titled, "[The Unfortunate Reality of Insecure
|
||||||
Libraries](https://www.aspectsecurity.com/uploads/downloads/2012/03/Aspect-Security-The-Unfortunate-Reality-of-Insecure-Libraries.pdf)".
|
Libraries](http://www1.contrastsecurity.com/the-unfortunate-reality-of-insecure-libraries?&__hssc=92971330.1.1412763139545&__hstc=92971330.5d71a97ce2c038f53e4109bfd029b71e.1412763139545.1412763139545.1412763139545.1&hsCtaTracking=7bbb964b-eac1-454d-9d5b-cc1089659590%7C816e01cf-4d75-449a-8691-bd0c6f9946a5)" (registration required).
|
||||||
The gist of the paper is that we as a development community include third party
|
The gist of the paper is that we as a development community include third party
|
||||||
libraries in our applications that contain well known published vulnerabilities
|
libraries in our applications that contain well known published vulnerabilities
|
||||||
\(such as those at the [National Vulnerability Database](http://web.nvd.nist.gov/view/vuln/search)\).
|
\(such as those at the [National Vulnerability Database](http://web.nvd.nist.gov/view/vuln/search)\).
|
||||||
|
|||||||
Reference in New Issue
Block a user