From 6a807bc002bbb0c869da9a8651935e6dc6abdf2d Mon Sep 17 00:00:00 2001
From: Jeremy Long
- * This analyzer ensures dependencies that should be grouped together, to remove excess noise from the report, are grouped. An
- * example would be Spring, Spring Beans, Spring MVC, etc. If they are all for the same version and have the same relative path
- * then these should be grouped into a single dependency under the core/main library.
- * Note, this grouping only works on dependencies with identified CVE entries
+ * Note, this grouping only works on dependencies with identified CVE + * entries * * @author Jeremy Long */ @@ -92,12 +95,14 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal // /** - * Analyzes a set of dependencies. If they have been found to have the same base path and the same set of identifiers they are - * likely related. The related dependencies are bundled into a single reportable item. + * Analyzes a set of dependencies. If they have been found to have the same + * base path and the same set of identifiers they are likely related. The + * related dependencies are bundled into a single reportable item. * * @param ignore this analyzer ignores the dependency being analyzed * @param engine the engine that is scanning the dependencies - * @throws AnalysisException is thrown if there is an error reading the JAR file. + * @throws AnalysisException is thrown if there is an error reading the JAR + * file. */ @Override public void analyze(Dependency ignore, Engine engine) throws AnalysisException { @@ -138,11 +143,11 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal mergeDependencies(nextDependency, dependency, dependenciesToRemove); break; //since we merged into the next dependency - skip forward to the next in mainIterator } - } else if ( isSameRubyGem(dependency, nextDependency) ) { - Dependency main = getMainGemspecDependency(dependency, nextDependency); - if (main == dependency) { - mergeDependencies(dependency, nextDependency, dependenciesToRemove); - } else { + } else if (isSameRubyGem(dependency, nextDependency)) { + final Dependency main = getMainGemspecDependency(dependency, nextDependency); + if (main == dependency) { + mergeDependencies(dependency, nextDependency, dependenciesToRemove); + } else { mergeDependencies(nextDependency, dependency, dependenciesToRemove); break; //since we merged into the next dependency - skip forward to the next in mainIterator } @@ -160,10 +165,11 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal * Adds the relatedDependency to the dependency's related dependencies. * * @param dependency the main dependency - * @param relatedDependency a collection of dependencies to be removed from the main analysis loop, this is the source of - * dependencies to remove - * @param dependenciesToRemove a collection of dependencies that will be removed from the main analysis loop, this function - * adds to this collection + * @param relatedDependency a collection of dependencies to be removed from + * the main analysis loop, this is the source of dependencies to remove + * @param dependenciesToRemove a collection of dependencies that will be + * removed from the main analysis loop, this function adds to this + * collection */ private void mergeDependencies(final Dependency dependency, final Dependency relatedDependency, final Settrue if the leftPath is the shortest; otherwise false
+ * @return true if the leftPath is the shortest; otherwise
+ * false
*/
protected boolean firstPathIsShortest(String left, String right) {
final String leftPath = left.replace('\\', '/');
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/FileNameAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/FileNameAnalyzer.java
index d8edade74..fcaaeb102 100644
--- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/FileNameAnalyzer.java
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/FileNameAnalyzer.java
@@ -70,7 +70,7 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
/**
* Python init files
*/
- private static final NameFileFilter IGNORED_FILES = new NameFileFilter(new String[] {
+ private static final NameFileFilter IGNORED_FILES = new NameFileFilter(new String[]{
"__init__.py",
"__init__.pyc",
"__init__.pyo",
@@ -81,7 +81,8 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
*
* @param dependency the dependency to analyze.
* @param engine the engine that is scanning the dependencies
- * @throws AnalysisException is thrown if there is an error reading the JAR file.
+ * @throws AnalysisException is thrown if there is an error reading the JAR
+ * file.
*/
@Override
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
@@ -107,13 +108,6 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
fileName, Confidence.MEDIUM);
}
- //add as vendor and product evidence
-// if (fileName.contains("-")) {
-// dependency.getProductEvidence().addEvidence("file", "name",
-// fileName, Confidence.HIGHEST);
-// dependency.getVendorEvidence().addEvidence("file", "name",
-// fileName, Confidence.HIGHEST);
-// } else
if (!IGNORED_FILES.accept(f)) {
dependency.getProductEvidence().addEvidence("file", "name",
fileName, Confidence.HIGH);
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java
index 4ffca8773..0423c5eeb 100644
--- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java
@@ -29,7 +29,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -578,7 +577,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
addMatchingValues(classes, trimmedDescription, dependency.getProductEvidence());
}
- String projectURL = pom.getProjectURL();
+ final String projectURL = pom.getProjectURL();
if (projectURL != null && !projectURL.trim().isEmpty()) {
dependency.getVendorEvidence().addEvidence("pom", "url", projectURL, Confidence.HIGHEST);
}
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.java
index 527892bce..9f12e0e95 100644
--- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.java
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.java
@@ -39,7 +39,8 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
- * Used to analyze a Python package, and collect information that can be used to determine the associated CPE.
+ * Used to analyze a Python package, and collect information that can be used to
+ * determine the associated CPE.
*
* @author Dale Visser
*/
@@ -166,7 +167,8 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
*
* @param dependency the dependency being analyzed
* @param engine the engine being used to perform the scan
- * @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency
+ * @throws AnalysisException thrown if there is an unrecoverable error
+ * analyzing the dependency
*/
@Override
protected void analyzeFileType(Dependency dependency, Engine engine)
@@ -175,21 +177,20 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
final File parent = file.getParentFile();
final String parentName = parent.getName();
if (INIT_PY_FILTER.accept(file)) {
- //by definition, the containing folder of __init__.py is considered the package, even the file is empty:
- //"The __init__.py files are required to make Python treat the directories as containing packages"
- //see section "6.4 Packages" from https://docs.python.org/2/tutorial/modules.html;
+ //by definition, the containing folder of __init__.py is considered the package, even the file is empty:
+ //"The __init__.py files are required to make Python treat the directories as containing packages"
+ //see section "6.4 Packages" from https://docs.python.org/2/tutorial/modules.html;
dependency.setDisplayFileName(parentName + "/__init__.py");
dependency.getProductEvidence().addEvidence(file.getName(),
"PackageName", parentName, Confidence.HIGHEST);
-
+
final File[] fileList = parent.listFiles(PY_FILTER);
if (fileList != null) {
for (final File sourceFile : fileList) {
analyzeFileContents(dependency, sourceFile);
}
}
- }
- else {
+ } else {
// copy, alter and set in case some other thread is iterating over
final ListDependency.getPackagePath() are the same.
- *
- * Ruby bundler creates new .gemspec files under a folder called "specifications" at deploy time,
- * in addition to the original .gemspec files from source. The bundler generated
- * .gemspec files always contain fully resolved attributes thus provide more accurate
- * evidences, whereas the original .gemspec from source often contain variables for attributes
- * that can't be used for evidences.
- *
- * Note this analyzer share the same {@link Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED} as
- * {@link RubyGemspecAnalyzer}, so it will enabled/disabled with {@link RubyGemspecAnalyzer}.
+ * This analyzer accepts the fully resolved .gemspec created by the Ruby bundler
+ * (http://bundler.io) for better evidence results. It also tries to resolve the
+ * dependency packagePath to where the gem is actually installed. Then during {@link AnalysisPhase.PRE_FINDING_ANALYSIS}
+ * {@link DependencyBundlingAnalyzer} will merge two .gemspec dependencies
+ * together if Dependency.getPackagePath() are the same.
+ *
+ * Ruby bundler creates new .gemspec files under a folder called
+ * "specifications" at deploy time, in addition to the original .gemspec files
+ * from source. The bundler generated .gemspec files always contain fully
+ * resolved attributes thus provide more accurate evidences, whereas the
+ * original .gemspec from source often contain variables for attributes that
+ * can't be used for evidences.
+ *
+ * Note this analyzer share the same
+ * {@link Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED} as
+ * {@link RubyGemspecAnalyzer}, so it will enabled/disabled with
+ * {@link RubyGemspecAnalyzer}.
*
* @author Bianca Jiang (biancajiang@gmail.com)
*/
@@ -48,12 +51,16 @@ public class RubyBundlerAnalyzer extends RubyGemspecAnalyzer {
* The name of the analyzer.
*/
private static final String ANALYZER_NAME = "Ruby Bundler Analyzer";
-
- //Folder name that contains .gemspec files created by "bundle install"
- private static final String SPECIFICATIONS = "specifications";
-
- //Folder name that contains the gems by "bundle install"
- private static final String GEMS = "gems";
+
+ /**
+ * Folder name that contains .gemspec files created by "bundle install"
+ */
+ private static final String SPECIFICATIONS = "specifications";
+
+ /**
+ * Folder name that contains the gems by "bundle install"
+ */
+ private static final String GEMS = "gems";
/**
* Returns the name of the analyzer.
@@ -66,61 +73,66 @@ public class RubyBundlerAnalyzer extends RubyGemspecAnalyzer {
}
/**
- * Only accept *.gemspec files generated by "bundle install --deployment" under "specifications" folder.
+ * Only accept *.gemspec files generated by "bundle install --deployment"
+ * under "specifications" folder.
+ *
+ * @param pathname the path name to test
+ * @return true if the analyzer can process the given file; otherwise false
*/
- @Override
+ @Override
public boolean accept(File pathname) {
-
+
boolean accepted = super.accept(pathname);
- if(accepted == true) {
- File parentDir = pathname.getParentFile();
- accepted = parentDir != null && parentDir.getName().equals(SPECIFICATIONS);
+ if (accepted) {
+ final File parentDir = pathname.getParentFile();
+ accepted = parentDir != null && parentDir.getName().equals(SPECIFICATIONS);
}
-
+
return accepted;
}
-
- @Override
+
+ @Override
protected void analyzeFileType(Dependency dependency, Engine engine)
throws AnalysisException {
super.analyzeFileType(dependency, engine);
-
+
//find the corresponding gem folder for this .gemspec stub by "bundle install --deployment"
- File gemspecFile = dependency.getActualFile();
- String gemFileName = gemspecFile.getName();
+ final File gemspecFile = dependency.getActualFile();
+ final String gemFileName = gemspecFile.getName();
final String gemName = gemFileName.substring(0, gemFileName.lastIndexOf(".gemspec"));
- File specificationsDir = gemspecFile.getParentFile();
- if(specificationsDir != null && specificationsDir.getName().equals(SPECIFICATIONS) && specificationsDir.exists()) {
- File parentDir = specificationsDir.getParentFile();
- if(parentDir != null && parentDir.exists()) {
- File gemsDir = new File(parentDir, GEMS);
- if(gemsDir != null && gemsDir.exists()) {
- File[] matchingFiles = gemsDir.listFiles(new FilenameFilter() {
- public boolean accept(File dir, String name) {
- return name.equals(gemName);
- }
- });
-
- if(matchingFiles.length > 0) {
- String gemPath = matchingFiles[0].getAbsolutePath();
- if(dependency.getActualFilePath().equals(dependency.getFilePath())) {
- if(gemPath != null)
- dependency.setPackagePath(gemPath);
- } else {
- //.gemspec's actualFilePath and filePath are different when it's from a compressed file
- //in which case actualFilePath is the temp directory used by decompression.
- //packagePath should use the filePath of the identified gem file in "gems" folder
- File gemspecStub = new File(dependency.getFilePath());
- File specDir = gemspecStub.getParentFile();
- if(specDir != null && specDir.getName().equals(SPECIFICATIONS)) {
- File gemsDir2 = new File(specDir.getParentFile(), GEMS);
- File packageDir = new File(gemsDir2, gemName);
- dependency.setPackagePath(packageDir.getAbsolutePath());
- }
- }
- }
- }
- }
- }
- }
+ final File specificationsDir = gemspecFile.getParentFile();
+ if (specificationsDir != null && specificationsDir.getName().equals(SPECIFICATIONS) && specificationsDir.exists()) {
+ final File parentDir = specificationsDir.getParentFile();
+ if (parentDir != null && parentDir.exists()) {
+ final File gemsDir = new File(parentDir, GEMS);
+ if (gemsDir.exists()) {
+ final File[] matchingFiles = gemsDir.listFiles(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return name.equals(gemName);
+ }
+ });
+
+ if (matchingFiles != null && matchingFiles.length > 0) {
+ final String gemPath = matchingFiles[0].getAbsolutePath();
+ if (dependency.getActualFilePath().equals(dependency.getFilePath())) {
+ if (gemPath != null) {
+ dependency.setPackagePath(gemPath);
+ }
+ } else {
+ //.gemspec's actualFilePath and filePath are different when it's from a compressed file
+ //in which case actualFilePath is the temp directory used by decompression.
+ //packagePath should use the filePath of the identified gem file in "gems" folder
+ final File gemspecStub = new File(dependency.getFilePath());
+ final File specDir = gemspecStub.getParentFile();
+ if (specDir != null && specDir.getName().equals(SPECIFICATIONS)) {
+ final File gemsDir2 = new File(specDir.getParentFile(), GEMS);
+ final File packageDir = new File(gemsDir2, gemName);
+ dependency.setPackagePath(packageDir.getAbsolutePath());
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java
index 8bad7cab2..2ee96b9db 100644
--- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java
@@ -34,15 +34,22 @@ import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.dependency.EvidenceCollection;
import org.owasp.dependencycheck.utils.FileFilterBuilder;
import org.owasp.dependencycheck.utils.Settings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
- * Used to analyze Ruby Gem specifications and collect information that can be used to determine the associated CPE. Regular
- * expressions are used to parse the well-defined Ruby syntax that forms the specification.
+ * Used to analyze Ruby Gem specifications and collect information that can be
+ * used to determine the associated CPE. Regular expressions are used to parse
+ * the well-defined Ruby syntax that forms the specification.
*
* @author Dale Visser
*/
public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
+ /**
+ * The logger.
+ */
+ private static final Logger LOGGER = LoggerFactory.getLogger(RubyGemspecAnalyzer.class);
/**
* The name of the analyzer.
*/
@@ -53,13 +60,22 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
*/
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
+ /**
+ * The gemspec file extension.
+ */
private static final String GEMSPEC = "gemspec";
- private static final FileFilter FILTER
- = FileFilterBuilder.newInstance().addExtensions(GEMSPEC).build();
- //TODO: support Rakefile
- //= FileFilterBuilder.newInstance().addExtensions(GEMSPEC).addFilenames("Rakefile").build();
+ /**
+ * The file filter containing the list of file extensions that can be
+ * analyzed.
+ */
+ private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(GEMSPEC).build();
+ //TODO: support Rakefile
+ //= FileFilterBuilder.newInstance().addExtensions(GEMSPEC).addFilenames("Rakefile").build();
+ /**
+ * The name of the version file.
+ */
private static final String VERSION_FILE_NAME = "VERSION";
/**
@@ -96,7 +112,8 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
}
/**
- * Returns the key used in the properties file to reference the analyzer's enabled property.
+ * Returns the key used in the properties file to reference the analyzer's
+ * enabled property.
*
* @return the analyzer's enabled property setting key
*/
@@ -108,8 +125,7 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
/**
* The capture group #1 is the block variable.
*/
- private static final Pattern GEMSPEC_BLOCK_INIT
- = Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|");
+ private static final Pattern GEMSPEC_BLOCK_INIT = Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|");
@Override
protected void analyzeFileType(Dependency dependency, Engine engine)
@@ -125,7 +141,7 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
if (matcher.find()) {
contents = contents.substring(matcher.end());
final String blockVariable = matcher.group(1);
-
+
final EvidenceCollection vendor = dependency.getVendorEvidence();
final EvidenceCollection product = dependency.getProductEvidence();
final String name = addStringEvidence(product, contents, blockVariable, "name", "name", Confidence.HIGHEST);
@@ -138,71 +154,90 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
addStringEvidence(vendor, contents, blockVariable, "email", "emails?", Confidence.MEDIUM);
addStringEvidence(vendor, contents, blockVariable, "homepage", "homepage", Confidence.HIGHEST);
addStringEvidence(vendor, contents, blockVariable, "license", "licen[cs]es?", Confidence.HIGHEST);
-
- String value = addStringEvidence(dependency.getVersionEvidence(), contents, blockVariable, "version", "version", Confidence.HIGHEST);
- if(value.length() < 1)
- addEvidenceFromVersionFile(dependency.getActualFile(), dependency.getVersionEvidence());
+
+ final String value = addStringEvidence(dependency.getVersionEvidence(), contents,
+ blockVariable, "version", "version", Confidence.HIGHEST);
+ if (value.length() < 1) {
+ addEvidenceFromVersionFile(dependency.getActualFile(), dependency.getVersionEvidence());
+ }
}
-
+
setPackagePath(dependency);
}
+ /**
+ * Adds the specified evidence to the given evidence collection.
+ *
+ * @param evidences the collection to add the evidence to
+ * @param contents the evidence contents
+ * @param blockVariable the variable
+ * @param field the field
+ * @param fieldPattern the field pattern
+ * @param confidence the confidence of the evidence
+ * @return the evidence string value added
+ */
private String addStringEvidence(EvidenceCollection evidences, String contents,
String blockVariable, String field, String fieldPattern, Confidence confidence) {
String value = "";
-
- //capture array value between [ ]
- final Matcher arrayMatcher = Pattern.compile(
+
+ //capture array value between [ ]
+ final Matcher arrayMatcher = Pattern.compile(
String.format("\\s*?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents);
- if(arrayMatcher.find()) {
- String arrayValue = arrayMatcher.group(1);
- value = arrayValue.replaceAll("['\"]", "").trim(); //strip quotes
- }
- //capture single value between quotes
- else {
- final Matcher matcher = Pattern.compile(
- String.format("\\s*?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents);
- if (matcher.find()) {
- value = matcher.group(2);
- }
- }
- if(value.length() > 0)
- evidences.addEvidence(GEMSPEC, field, value, confidence);
-
+ if (arrayMatcher.find()) {
+ final String arrayValue = arrayMatcher.group(1);
+ value = arrayValue.replaceAll("['\"]", "").trim(); //strip quotes
+ } else { //capture single value between quotes
+ final Matcher matcher = Pattern.compile(
+ String.format("\\s*?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, fieldPattern), Pattern.CASE_INSENSITIVE).matcher(contents);
+ if (matcher.find()) {
+ value = matcher.group(2);
+ }
+ }
+ if (value.length() > 0) {
+ evidences.addEvidence(GEMSPEC, field, value, confidence);
+ }
+
return value;
}
-
- private String addEvidenceFromVersionFile(File dependencyFile, EvidenceCollection versionEvidences) {
- String value = null;
- File parentDir = dependencyFile.getParentFile();
- if(parentDir != null) {
- File[] matchingFiles = parentDir.listFiles(new FilenameFilter() {
- public boolean accept(File dir, String name) {
- return name.contains(VERSION_FILE_NAME);
- }
- });
-
- for(int i = 0; i < matchingFiles.length; i++) {
- try {
- List* Gets the file path of the dependency.
*- * NOTE: This may not be the actual path of the file on disk. The actual path of the file on disk can be obtained via - * the getActualFilePath().
+ * NOTE: This may not be the actual path of the file on disk. The + * actual path of the file on disk can be obtained via the + * getActualFilePath(). * * @return the file path of the dependency */ @@ -299,7 +318,8 @@ public class Dependency implements Serializable, Comparable- * A utility function that will interpolate strings based on values given in the properties file. It will also interpolate the - * strings contained within the properties file so that properties can reference other properties.
+ * A utility function that will interpolate strings based on values given in + * the properties file. It will also interpolate the strings contained + * within the properties file so that properties can reference other + * properties. *- * Note: if there is no property found the reference will be removed. In other words, if the interpolated string will - * be replaced with an empty string. + * Note: if there is no property found the reference will be removed. + * In other words, if the interpolated string will be replaced with an empty + * string. *
** Example:
@@ -329,7 +332,8 @@ public class Model { * * * @param text the string that contains references to properties. - * @param properties a collection of properties that may be referenced within the text. + * @param properties a collection of properties that may be referenced + * within the text. * @return the interpolated text. */ public static String interpolateString(String text, Properties properties) { @@ -340,8 +344,9 @@ public class Model { return substitutor.replace(text); } - /** - * Utility class that can provide values from a Properties object to a StrSubstitutor. + /** + * Utility class that can provide values from a Properties object to a + * StrSubstitutor. */ private static class PropertyLookup extends StrLookup { diff --git a/src/main/config/checkstyle-header.txt b/src/main/config/checkstyle-header.txt index c2ceba9ef..2e87cd304 100644 --- a/src/main/config/checkstyle-header.txt +++ b/src/main/config/checkstyle-header.txt @@ -13,6 +13,6 @@ ^ \* See the License for the specific language governing permissions and\s*$ ^ \* limitations under the License\.\s*$ ^ \*\s*$ -^ \* Copyright \(c\) 201[0-9] (Jeremy Long|Steve Springett|The OWASP Foundation|Institute for Defense Analyses)\. All Rights Reserved\.\s*$ +^ \* Copyright \(c\) 201[0-9] (Jeremy Long|Steve Springett|Bianca Jiang|The OWASP Foundation|Institute for Defense Analyses)\. All Rights Reserved\.\s*$ ^ \*/\s*$ ^package