From 6007be1b5fb32f2c491496803daeb295f756e811 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 20 May 2017 07:37:46 -0400 Subject: [PATCH 01/23] updated to resolve issue #696 --- .../java/org/owasp/dependencycheck/App.java | 13 +-- .../org/owasp/dependencycheck/CliParser.java | 72 +++++++++----- .../org/owasp/dependencycheck/AppTest.java | 96 +++++++++++++++++-- .../src/test/resources/sample.properties | 33 +++++++ .../src/test/resources/sample2.properties | 33 +++++++ pom.xml | 1 + 6 files changed, 209 insertions(+), 39 deletions(-) create mode 100644 dependency-check-cli/src/test/resources/sample.properties create mode 100644 dependency-check-cli/src/test/resources/sample2.properties diff --git a/dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java b/dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java index 52c6fce77..399dd15b3 100644 --- a/dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java +++ b/dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java @@ -353,8 +353,7 @@ public class App { * @throws InvalidSettingException thrown when a user defined properties * file is unable to be loaded. */ - private void populateSettings(CliParser cli) throws InvalidSettingException { - final boolean autoUpdate = cli.isAutoUpdate(); + protected void populateSettings(CliParser cli) throws InvalidSettingException { final String connectionTimeout = cli.getConnectionTimeout(); final String proxyServer = cli.getProxyServer(); final String proxyPort = cli.getProxyPort(); @@ -377,7 +376,8 @@ public class App { final String cveBase12 = cli.getBaseCve12Url(); final String cveBase20 = cli.getBaseCve20Url(); final Integer cveValidForHours = cli.getCveValidForHours(); - final boolean experimentalEnabled = cli.isExperimentalEnabled(); + final Boolean autoUpdate = cli.isAutoUpdate(); + final Boolean experimentalEnabled = cli.isExperimentalEnabled(); if (propertiesFile != null) { try { @@ -390,7 +390,7 @@ public class App { } // We have to wait until we've merged the properties before attempting to set whether we use // the proxy for Nexus since it could be disabled in the properties, but not explicitly stated - // on the command line + // on the command line. This is true of other boolean values set below not using the setBooleanIfNotNull. final boolean nexusUsesProxy = cli.isNexusUsesProxy(); if (dataDirectory != null) { Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory); @@ -404,7 +404,7 @@ public class App { final File dataDir = new File(base, sub); Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); } - Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); + Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate); Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer); Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort); Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUser); @@ -415,7 +415,8 @@ public class App { Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours); //File Type Analyzer Settings - Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, experimentalEnabled); + Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, experimentalEnabled); + Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, !cli.isJarDisabled()); Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, !cli.isArchiveDisabled()); Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, !cli.isPythonDistributionDisabled()); diff --git a/dependency-check-cli/src/main/java/org/owasp/dependencycheck/CliParser.java b/dependency-check-cli/src/main/java/org/owasp/dependencycheck/CliParser.java index c259e50d0..2ac6152c6 100644 --- a/dependency-check-cli/src/main/java/org/owasp/dependencycheck/CliParser.java +++ b/dependency-check-cli/src/main/java/org/owasp/dependencycheck/CliParser.java @@ -567,6 +567,32 @@ public final class CliParser { return value; } + /** + * Utility method to determine if one of the disable options has been set. + * If not set, this method will check the currently configured settings for + * the current value to return. + * + * Example given `--disableArchive` on the command line would cause this + * method to return true for the disable archive setting. + * + * @param argument the command line argument + * @param setting the corresponding settings key + * @return true if the disable option was set, if not set the currently + * configured value will be returned + */ + private boolean hasDisableOption(String argument, String setting) { + if (line == null || !line.hasOption(argument)) { + try { + return !Settings.getBoolean(setting); + } catch (InvalidSettingException ise) { + LOGGER.warn("Invalid property setting '{}' defaulting to false", setting); + return false; + } + } else { + return true; + } + } + /** * Returns true if the disableJar command line argument was specified. * @@ -574,7 +600,7 @@ public final class CliParser { * otherwise false */ public boolean isJarDisabled() { - return (line != null) && line.hasOption(ARGUMENT.DISABLE_JAR); + return hasDisableOption(ARGUMENT.DISABLE_JAR, Settings.KEYS.ANALYZER_JAR_ENABLED); } /** @@ -584,7 +610,7 @@ public final class CliParser { * otherwise false */ public boolean isArchiveDisabled() { - return (line != null) && line.hasOption(ARGUMENT.DISABLE_ARCHIVE); + return hasDisableOption(ARGUMENT.DISABLE_ARCHIVE, Settings.KEYS.ANALYZER_ARCHIVE_ENABLED); } /** @@ -594,7 +620,7 @@ public final class CliParser { * otherwise false */ public boolean isNuspecDisabled() { - return (line != null) && line.hasOption(ARGUMENT.DISABLE_NUSPEC); + return hasDisableOption(ARGUMENT.DISABLE_NUSPEC, Settings.KEYS.ANALYZER_NUSPEC_ENABLED); } /** @@ -604,7 +630,7 @@ public final class CliParser { * otherwise false */ public boolean isAssemblyDisabled() { - return (line != null) && line.hasOption(ARGUMENT.DISABLE_ASSEMBLY); + return hasDisableOption(ARGUMENT.DISABLE_ASSEMBLY, Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED); } /** @@ -615,7 +641,7 @@ public final class CliParser { * specified; otherwise false */ public boolean isBundleAuditDisabled() { - return (line != null) && line.hasOption(ARGUMENT.DISABLE_BUNDLE_AUDIT); + return hasDisableOption(ARGUMENT.DISABLE_BUNDLE_AUDIT, Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED); } /** @@ -625,7 +651,7 @@ public final class CliParser { * otherwise false */ public boolean isPythonDistributionDisabled() { - return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_DIST); + return hasDisableOption(ARGUMENT.DISABLE_PY_DIST, Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED); } /** @@ -635,7 +661,7 @@ public final class CliParser { * otherwise false */ public boolean isPythonPackageDisabled() { - return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_PKG); + return hasDisableOption(ARGUMENT.DISABLE_PY_PKG, Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED); } /** @@ -645,7 +671,7 @@ public final class CliParser { * argument was specified; otherwise false */ public boolean isRubyGemspecDisabled() { - return (null != line) && line.hasOption(ARGUMENT.DISABLE_RUBYGEMS); + return hasDisableOption(ARGUMENT.DISABLE_RUBYGEMS, Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED); } /** @@ -655,7 +681,7 @@ public final class CliParser { * otherwise false */ public boolean isCmakeDisabled() { - return (line != null) && line.hasOption(ARGUMENT.DISABLE_CMAKE); + return hasDisableOption(ARGUMENT.DISABLE_CMAKE, Settings.KEYS.ANALYZER_CMAKE_ENABLED); } /** @@ -665,7 +691,7 @@ public final class CliParser { * otherwise false */ public boolean isAutoconfDisabled() { - return (line != null) && line.hasOption(ARGUMENT.DISABLE_AUTOCONF); + return hasDisableOption(ARGUMENT.DISABLE_AUTOCONF, Settings.KEYS.ANALYZER_AUTOCONF_ENABLED); } /** @@ -675,7 +701,7 @@ public final class CliParser { * otherwise false */ public boolean isComposerDisabled() { - return (line != null) && line.hasOption(ARGUMENT.DISABLE_COMPOSER); + return hasDisableOption(ARGUMENT.DISABLE_COMPOSER, Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED); } /** @@ -685,7 +711,7 @@ public final class CliParser { * otherwise false */ public boolean isNexusDisabled() { - return (line != null) && line.hasOption(ARGUMENT.DISABLE_NEXUS); + return hasDisableOption(ARGUMENT.DISABLE_NEXUS, Settings.KEYS.ANALYZER_NEXUS_ENABLED); } /** @@ -695,7 +721,7 @@ public final class CliParser { * otherwise false */ public boolean isOpenSSLDisabled() { - return (line != null) && line.hasOption(ARGUMENT.DISABLE_OPENSSL); + return hasDisableOption(ARGUMENT.DISABLE_OPENSSL, Settings.KEYS.ANALYZER_OPENSSL_ENABLED); } /** @@ -705,7 +731,7 @@ public final class CliParser { * otherwise false */ public boolean isNodeJsDisabled() { - return (line != null) && line.hasOption(ARGUMENT.DISABLE_NODE_JS); + return hasDisableOption(ARGUMENT.DISABLE_NODE_JS, Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED); } /** @@ -716,7 +742,7 @@ public final class CliParser { * specified; otherwise false */ public boolean isCocoapodsAnalyzerDisabled() { - return (line != null) && line.hasOption(ARGUMENT.DISABLE_COCOAPODS); + return hasDisableOption(ARGUMENT.DISABLE_COCOAPODS, Settings.KEYS.ANALYZER_COCOAPODS_ENABLED); } /** @@ -727,7 +753,7 @@ public final class CliParser { * argument was specified; otherwise false */ public boolean isSwiftPackageAnalyzerDisabled() { - return (line != null) && line.hasOption(ARGUMENT.DISABLE_SWIFT); + return hasDisableOption(ARGUMENT.DISABLE_SWIFT, Settings.KEYS.ANALYZER_SWIFT_PACKAGE_MANAGER_ENABLED); } /** @@ -737,7 +763,7 @@ public final class CliParser { * otherwise false */ public boolean isCentralDisabled() { - return (line != null) && line.hasOption(ARGUMENT.DISABLE_CENTRAL); + return hasDisableOption(ARGUMENT.DISABLE_CENTRAL, Settings.KEYS.ANALYZER_CENTRAL_ENABLED); } /** @@ -1029,10 +1055,10 @@ public final class CliParser { * disabled via the command line this will return false. * * @return true if auto-update is allowed; otherwise - * false + * null */ - public boolean isAutoUpdate() { - return line != null && !line.hasOption(ARGUMENT.DISABLE_AUTO_UPDATE); + public Boolean isAutoUpdate() { + return (line != null && line.hasOption(ARGUMENT.DISABLE_AUTO_UPDATE)) ? false : null; } /** @@ -1134,10 +1160,10 @@ public final class CliParser { /** * Returns true if the experimental analyzers are enabled. * - * @return true if the experimental analyzers are enabled; otherwise false + * @return true if the experimental analyzers are enabled; otherwise null */ - public boolean isExperimentalEnabled() { - return line.hasOption(ARGUMENT.EXPERIMENTAL); + public Boolean isExperimentalEnabled() { + return (line != null && line.hasOption(ARGUMENT.EXPERIMENTAL)) ? true : null; } /** diff --git a/dependency-check-cli/src/test/java/org/owasp/dependencycheck/AppTest.java b/dependency-check-cli/src/test/java/org/owasp/dependencycheck/AppTest.java index fdadb0e39..e6569e761 100644 --- a/dependency-check-cli/src/test/java/org/owasp/dependencycheck/AppTest.java +++ b/dependency-check-cli/src/test/java/org/owasp/dependencycheck/AppTest.java @@ -13,18 +13,28 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * Copyright (c) 2015 The OWASP Foundatio. All Rights Reserved. + * Copyright (c) 2017 The OWASP Foundatio. All Rights Reserved. */ package org.owasp.dependencycheck; +import java.io.File; +import java.io.FileNotFoundException; +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.Map; +import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.UnrecognizedOptionException; import org.junit.Test; import static org.junit.Assert.*; +import org.owasp.dependencycheck.utils.InvalidSettingException; +import org.owasp.dependencycheck.utils.Settings; /** * * @author jeremy */ public class AppTest { + /** * Test of ensureCanonicalPath method, of class App. */ @@ -35,17 +45,83 @@ public class AppTest { String result = instance.ensureCanonicalPath(file); assertFalse(result.contains("..")); assertTrue(result.endsWith("*.jar")); - } - /** - * Test of ensureCanonicalPath method, of class App. - */ - @Test - public void testEnsureCanonicalPath2() { - String file = "../some/skip/../path/file.txt"; - App instance = new App(); + file = "../some/skip/../path/file.txt"; String expResult = "/some/path/file.txt"; - String result = instance.ensureCanonicalPath(file); + result = instance.ensureCanonicalPath(file); assertTrue("result=" + result, result.endsWith(expResult)); } + + @Test(expected = UnrecognizedOptionException.class) + public void testPopulateSettingsException() throws FileNotFoundException, ParseException, InvalidSettingException, URISyntaxException { + String[] args = {"-invalidPROPERTY"}; + assertTrue(testBooleanProperties(args, null)); + } + + @Test + public void testPopulateSettings() throws FileNotFoundException, ParseException, InvalidSettingException, URISyntaxException { + File prop = new File(this.getClass().getClassLoader().getResource("sample.properties").toURI().getPath()); + String[] args = {"-P", prop.getAbsolutePath()}; + Map expected = new HashMap<>(); + expected.put(Settings.KEYS.AUTO_UPDATE, Boolean.FALSE); + expected.put(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, Boolean.TRUE); + + assertTrue(testBooleanProperties(args, expected)); + + String[] args2 = {"-n"}; + expected.put(Settings.KEYS.AUTO_UPDATE, Boolean.FALSE); + expected.put(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, Boolean.TRUE); + assertTrue(testBooleanProperties(args2, expected)); + + String[] args3 = {"-h"}; + expected.put(Settings.KEYS.AUTO_UPDATE, Boolean.TRUE); + expected.put(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, Boolean.TRUE); + assertTrue(testBooleanProperties(args3, expected)); + + String[] args4 = {"--disableArchive"}; + expected.put(Settings.KEYS.AUTO_UPDATE, Boolean.TRUE); + expected.put(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, Boolean.FALSE); + assertTrue(testBooleanProperties(args4, expected)); + + String[] args5 = {"-P", prop.getAbsolutePath(), "--disableArchive"}; + expected.put(Settings.KEYS.AUTO_UPDATE, Boolean.FALSE); + expected.put(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, Boolean.FALSE); + assertTrue(testBooleanProperties(args5, expected)); + + prop = new File(this.getClass().getClassLoader().getResource("sample2.properties").toURI().getPath()); + String[] args6 = {"-P", prop.getAbsolutePath(), "--disableArchive"}; + expected.put(Settings.KEYS.AUTO_UPDATE, Boolean.TRUE); + expected.put(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, Boolean.FALSE); + assertTrue(testBooleanProperties(args6, expected)); + + String[] args7 = {"-P", prop.getAbsolutePath(), "--noupdate"}; + expected.put(Settings.KEYS.AUTO_UPDATE, Boolean.FALSE); + expected.put(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, Boolean.TRUE); + assertTrue(testBooleanProperties(args7, expected)); + + String[] args8 = {"-P", prop.getAbsolutePath(), "--noupdate", "--disableArchive"}; + expected.put(Settings.KEYS.AUTO_UPDATE, Boolean.FALSE); + expected.put(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, Boolean.FALSE); + assertTrue(testBooleanProperties(args8, expected)); + + + } + + private boolean testBooleanProperties(String[] args, Map expected) throws URISyntaxException, FileNotFoundException, ParseException, InvalidSettingException { + Settings.initialize(); + try { + final CliParser cli = new CliParser(); + cli.parse(args); + App instance = new App(); + instance.populateSettings(cli); + boolean results = true; + for (Map.Entry entry : expected.entrySet()) { + results &= Settings.getBoolean(entry.getKey()) == entry.getValue(); + } + + return results; + } finally { + Settings.cleanup(); + } + } } diff --git a/dependency-check-cli/src/test/resources/sample.properties b/dependency-check-cli/src/test/resources/sample.properties new file mode 100644 index 000000000..0b45d5d04 --- /dev/null +++ b/dependency-check-cli/src/test/resources/sample.properties @@ -0,0 +1,33 @@ +autoupdate=false + +analyzer.experimental.enabled=false +analyzer.jar.enabled=true +analyzer.archive.enabled=true +analyzer.node.package.enabled=true +analyzer.composer.lock.enabled=true +analyzer.python.distribution.enabled=true +analyzer.python.package.enabled=true +analyzer.ruby.gemspec.enabled=true +analyzer.autoconf.enabled=true +analyzer.cmake.enabled=true +analyzer.assembly.enabled=true +analyzer.nuspec.enabled=true +analyzer.openssl.enabled=true +analyzer.central.enabled=true +analyzer.nexus.enabled=false +analyzer.cocoapods.enabled=true +analyzer.swift.package.manager.enabled=true +#whether the nexus analyzer uses the proxy +analyzer.nexus.proxy=true +analyzer.cpe.enabled=true +analyzer.cpesuppression.enabled=true +analyzer.dependencybundling.enabled=true +analyzer.dependencymerging.enabled=true +analyzer.falsepositive.enabled=true +analyzer.filename.enabled=true +analyzer.hint.enabled=true +analyzer.nvdcve.enabled=true +analyzer.vulnerabilitysuppression.enabled=true +updater.nvdcve.enabled=true +updater.versioncheck.enabled=true +analyzer.versionfilter.enabled=true \ No newline at end of file diff --git a/dependency-check-cli/src/test/resources/sample2.properties b/dependency-check-cli/src/test/resources/sample2.properties new file mode 100644 index 000000000..34a2efe65 --- /dev/null +++ b/dependency-check-cli/src/test/resources/sample2.properties @@ -0,0 +1,33 @@ +autoupdate=true + +analyzer.experimental.enabled=false +analyzer.jar.enabled=true +analyzer.archive.enabled=true +analyzer.node.package.enabled=true +analyzer.composer.lock.enabled=true +analyzer.python.distribution.enabled=true +analyzer.python.package.enabled=true +analyzer.ruby.gemspec.enabled=true +analyzer.autoconf.enabled=true +analyzer.cmake.enabled=true +analyzer.assembly.enabled=true +analyzer.nuspec.enabled=true +analyzer.openssl.enabled=true +analyzer.central.enabled=true +analyzer.nexus.enabled=false +analyzer.cocoapods.enabled=true +analyzer.swift.package.manager.enabled=true +#whether the nexus analyzer uses the proxy +analyzer.nexus.proxy=true +analyzer.cpe.enabled=true +analyzer.cpesuppression.enabled=true +analyzer.dependencybundling.enabled=true +analyzer.dependencymerging.enabled=true +analyzer.falsepositive.enabled=true +analyzer.filename.enabled=true +analyzer.hint.enabled=true +analyzer.nvdcve.enabled=true +analyzer.vulnerabilitysuppression.enabled=true +updater.nvdcve.enabled=true +updater.versioncheck.enabled=true +analyzer.versionfilter.enabled=true \ No newline at end of file diff --git a/pom.xml b/pom.xml index 370e4c9fd..f49db6716 100644 --- a/pom.xml +++ b/pom.xml @@ -134,6 +134,7 @@ Copyright (c) 2012 - Jeremy Long 3.0 2.17 3.6 + From e8e06d12c78d592eb7cd3c2450d4f43795b715f1 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sun, 21 May 2017 07:25:42 -0400 Subject: [PATCH 02/23] updated for code coverage --- .../org/owasp/dependencycheck/AppTest.java | 2 +- .../src/test/resources/sample2.properties | 60 +++++++++---------- pom.xml | 28 ++++++++- 3 files changed, 56 insertions(+), 34 deletions(-) diff --git a/dependency-check-cli/src/test/java/org/owasp/dependencycheck/AppTest.java b/dependency-check-cli/src/test/java/org/owasp/dependencycheck/AppTest.java index e6569e761..9659c5241 100644 --- a/dependency-check-cli/src/test/java/org/owasp/dependencycheck/AppTest.java +++ b/dependency-check-cli/src/test/java/org/owasp/dependencycheck/AppTest.java @@ -96,7 +96,7 @@ public class AppTest { String[] args7 = {"-P", prop.getAbsolutePath(), "--noupdate"}; expected.put(Settings.KEYS.AUTO_UPDATE, Boolean.FALSE); - expected.put(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, Boolean.TRUE); + expected.put(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, Boolean.FALSE); assertTrue(testBooleanProperties(args7, expected)); String[] args8 = {"-P", prop.getAbsolutePath(), "--noupdate", "--disableArchive"}; diff --git a/dependency-check-cli/src/test/resources/sample2.properties b/dependency-check-cli/src/test/resources/sample2.properties index 34a2efe65..00d0e5a27 100644 --- a/dependency-check-cli/src/test/resources/sample2.properties +++ b/dependency-check-cli/src/test/resources/sample2.properties @@ -1,33 +1,33 @@ autoupdate=true -analyzer.experimental.enabled=false -analyzer.jar.enabled=true -analyzer.archive.enabled=true -analyzer.node.package.enabled=true -analyzer.composer.lock.enabled=true -analyzer.python.distribution.enabled=true -analyzer.python.package.enabled=true -analyzer.ruby.gemspec.enabled=true -analyzer.autoconf.enabled=true -analyzer.cmake.enabled=true -analyzer.assembly.enabled=true -analyzer.nuspec.enabled=true -analyzer.openssl.enabled=true -analyzer.central.enabled=true -analyzer.nexus.enabled=false -analyzer.cocoapods.enabled=true -analyzer.swift.package.manager.enabled=true +analyzer.experimental.enabled=true +analyzer.jar.enabled=false +analyzer.archive.enabled=false +analyzer.node.package.enabled=false +analyzer.composer.lock.enabled=false +analyzer.python.distribution.enabled=false +analyzer.python.package.enabled=false +analyzer.ruby.gemspec.enabled=false +analyzer.autoconf.enabled=false +analyzer.cmake.enabled=false +analyzer.assembly.enabled=false +analyzer.nuspec.enabled=false +analyzer.openssl.enabled=false +analyzer.central.enabled=false +analyzer.nexus.enabled=true +analyzer.cocoapods.enabled=false +analyzer.swift.package.manager.enabled=false #whether the nexus analyzer uses the proxy -analyzer.nexus.proxy=true -analyzer.cpe.enabled=true -analyzer.cpesuppression.enabled=true -analyzer.dependencybundling.enabled=true -analyzer.dependencymerging.enabled=true -analyzer.falsepositive.enabled=true -analyzer.filename.enabled=true -analyzer.hint.enabled=true -analyzer.nvdcve.enabled=true -analyzer.vulnerabilitysuppression.enabled=true -updater.nvdcve.enabled=true -updater.versioncheck.enabled=true -analyzer.versionfilter.enabled=true \ No newline at end of file +analyzer.nexus.proxy=false +analyzer.cpe.enabled=false +analyzer.cpesuppression.enabled=false +analyzer.dependencybundling.enabled=false +analyzer.dependencymerging.enabled=false +analyzer.falsepositive.enabled=false +analyzer.filename.enabled=false +analyzer.hint.enabled=false +analyzer.nvdcve.enabled=false +analyzer.vulnerabilitysuppression.enabled=false +updater.nvdcve.enabled=false +updater.versioncheck.enabled=false +analyzer.versionfilter.enabled=false \ No newline at end of file diff --git a/pom.xml b/pom.xml index f49db6716..9b371cead 100644 --- a/pom.xml +++ b/pom.xml @@ -134,7 +134,6 @@ Copyright (c) 2012 - Jeremy Long 3.0 2.17 3.6 - @@ -289,7 +288,7 @@ Copyright (c) 2012 - Jeremy Long prepare-agent - + ${project.build.directory}/coverage-reports/jacoco-ut.exec surefireArgLine @@ -300,12 +299,31 @@ Copyright (c) 2012 - Jeremy Long prepare-agent - + ${project.build.directory}/coverage-reports/jacoco-it.exec failsafeArgLine + + org.codehaus.gmaven + gmaven-plugin + 1.5 + + + add-dynamic-properties + pre-integration-test + + execute + + + + project.properties['invoker.mavenOpts']=project.properties.failsafeArgLine + + + + + org.apache.maven.plugins maven-surefire-plugin @@ -579,6 +597,10 @@ Copyright (c) 2012 - Jeremy Long jacoco-maven-plugin 0.7.9 + + target/coverage-reports/jacoco-ut.exec + target/coverage-reports/jacoco-it.exec + From 8eff6283030550eb609ac52b3e88853ce095c951 Mon Sep 17 00:00:00 2001 From: Seth Jackson Date: Tue, 23 May 2017 14:43:02 -0400 Subject: [PATCH 03/23] Update Windows usage. So that the example invocation works in PowerShell and cmd. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f14f03c16..eca8c088d 100644 --- a/README.md +++ b/README.md @@ -29,8 +29,8 @@ $ ./bin/dependency-check.sh --project Testing --out . --scan [path to jar files ``` On Windows ``` -> bin/dependency-check.bat -h -> bin/dependency-check.bat --project Testing --out . --scan [path to jar files to be scanned] +> .\bin\dependency-check.bat -h +> .\bin\dependency-check.bat --project Testing --out . --scan [path to jar files to be scanned] ``` On Mac with [Homebrew](http://brew.sh) ``` From 2dbfba9ac5cbb63a986f0b4d92daac7a7c667149 Mon Sep 17 00:00:00 2001 From: Seth Jackson Date: Tue, 23 May 2017 16:01:11 -0400 Subject: [PATCH 04/23] Fix wording. --- src/site/markdown/data/database.md.vm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/site/markdown/data/database.md.vm b/src/site/markdown/data/database.md.vm index b5a6b514d..018a90284 100644 --- a/src/site/markdown/data/database.md.vm +++ b/src/site/markdown/data/database.md.vm @@ -20,8 +20,8 @@ To setup a centralized database the following generalized steps can be used:
  1. Create the database and tables using either initialize.sql or one of the other initialization scripts found here.
  2. The account that the clients will connect using must have select granted on the tables. -
    • Note, if the clients performing the scans should run with the noupdate setting. A single - instance of the dependency-check client should be setup with update enabled and the account +
      • Note, the clients performing the scans should run with the noupdate setting. A single + instance of the dependency-check client should be setup with updates enabled and the account used during the update process will need to be granted update rights on the tables.
    • Dependency-check clients running scans will need to be configured to use the central database: From c96ef88222c3c6e209d1d474ebb00a46f07ad7f7 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Tue, 23 May 2017 21:00:40 -0400 Subject: [PATCH 05/23] Moved report generation into the engine, cleaned up code, etc. --- .../owasp/dependencycheck/taskdefs/Check.java | 11 +- .../java/org/owasp/dependencycheck/App.java | 14 +- .../org/owasp/dependencycheck/Engine.java | 41 ++ .../agent/DependencyCheckScanAgent.java | 20 +- .../reporting/ReportGenerator.java | 434 +++++++++--------- .../{CsvReport.vsl => csvReport.vsl} | 0 .../{HtmlReport.vsl => htmlReport.vsl} | 0 .../{JsonReport.vsl => jsonReport.vsl} | 0 ...VulnerabilityReport.vsl => vulnReport.vsl} | 0 .../{XmlReport.vsl => xmlReport.vsl} | 0 .../org/owasp/dependencycheck/EngineIT.java | 8 +- .../reporting/ReportGeneratorIT.java | 81 +--- .../dependencycheck/maven/AggregateMojo.java | 3 +- .../maven/BaseDependencyCheckMojo.java | 29 -- .../dependencycheck/maven/CheckMojo.java | 19 +- 15 files changed, 295 insertions(+), 365 deletions(-) rename dependency-check-core/src/main/resources/templates/{CsvReport.vsl => csvReport.vsl} (100%) rename dependency-check-core/src/main/resources/templates/{HtmlReport.vsl => htmlReport.vsl} (100%) rename dependency-check-core/src/main/resources/templates/{JsonReport.vsl => jsonReport.vsl} (100%) rename dependency-check-core/src/main/resources/templates/{VulnerabilityReport.vsl => vulnReport.vsl} (100%) rename dependency-check-core/src/main/resources/templates/{XmlReport.vsl => xmlReport.vsl} (100%) diff --git a/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/Check.java b/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/Check.java index d69b3ecbe..05bab0aae 100644 --- a/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/Check.java +++ b/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/Check.java @@ -940,16 +940,7 @@ public class Check extends Update { throw new BuildException(ex); } } - DatabaseProperties prop = null; - try (CveDB cve = CveDB.getInstance()) { - prop = cve.getDatabaseProperties(); - } catch (DatabaseException ex) { - //TODO shouldn't this be a fatal exception - log("Unable to retrieve DB Properties", ex, Project.MSG_DEBUG); - } - - final ReportGenerator reporter = new ReportGenerator(getProjectName(), engine.getDependencies(), engine.getAnalyzers(), prop); - reporter.generateReports(reportOutputDirectory, reportFormat); + engine.writeReports(getProjectName(),new File(reportOutputDirectory), reportFormat); if (this.failBuildOnCVSS <= 10) { checkForFailure(engine.getDependencies()); diff --git a/dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java b/dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java index 399dd15b3..8b7b709f3 100644 --- a/dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java +++ b/dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java @@ -281,18 +281,9 @@ public class App { } exCol = ex; } - final List dependencies = engine.getDependencies(); - DatabaseProperties prop = null; - try (CveDB cve = CveDB.getInstance()) { - prop = cve.getDatabaseProperties(); - } catch (DatabaseException ex) { - //TODO shouldn't this be a fatal exception - LOGGER.debug("Unable to retrieve DB Properties", ex); - } - final ReportGenerator report = new ReportGenerator(applicationName, dependencies, engine.getAnalyzers(), prop); try { - report.generateReports(reportDirectory, outputFormat); + engine.writeReports(applicationName, new File(reportDirectory), outputFormat); } catch (ReportException ex) { if (exCol != null) { exCol.addException(ex); @@ -306,7 +297,7 @@ public class App { } //Set the exit code based on whether we found a high enough vulnerability - for (Dependency dep : dependencies) { + for (Dependency dep : engine.getDependencies()) { if (!dep.getVulnerabilities().isEmpty()) { for (Vulnerability vuln : dep.getVulnerabilities()) { LOGGER.debug("VULNERABILITY FOUND " + dep.getDisplayFileName()); @@ -316,7 +307,6 @@ public class App { } } } - return retCode; } finally { if (engine != null) { diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java index bfbc066c8..e50d625aa 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java @@ -54,6 +54,9 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; +import org.owasp.dependencycheck.exception.ReportException; +import org.owasp.dependencycheck.reporting.ReportGenerator; /** * Scans files, directories, etc. for Dependencies. Analyzers are loaded and @@ -796,4 +799,42 @@ public class Engine implements FileFilter { exceptions.add(throwable); throw new ExceptionCollection(message, exceptions, true); } + + /** + * Writes the report to the given output directory. + * + * @param applicationName the name of the application/project + * @param groupId the Maven groupId + * @param artifactId the Maven artifactId + * @param version the Maven version + * @param outputDir the path to the output directory (can include the full + * file name if the format is not ALL) + * @param format the report format (ALL, HTML, CSV, JSON, etc.) + * @throws ReportException thrown if there is an error generating the report + */ + public void writeReports(String applicationName, String groupId, String artifactId, + String version, File outputDir, String format) throws ReportException { + + DatabaseProperties prop = database.getDatabaseProperties(); + final ReportGenerator r = new ReportGenerator(applicationName, groupId, artifactId, version, dependencies, getAnalyzers(), prop); + try { + r.write(outputDir.getAbsolutePath(), format); + } catch (ReportException ex) { + final String msg = String.format("Error generating the report for %s", applicationName); + throw new ReportException(msg, ex); + } + } + + /** + * Writes the report to the given output directory. + * + * @param applicationName the name of the application/project + * @param outputDir the path to the output directory (can include the full + * file name if the format is not ALL) + * @param format the report format (ALL, HTML, CSV, JSON, etc.) + * @throws ReportException thrown if there is an error generating the report + */ + public void writeReports(String applicationName, File outputDir, String format) throws ReportException { + writeReports(applicationName, null, null, null, outputDir, format); + } } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.java index 2ee63b1f6..c862d0fc1 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.java @@ -840,21 +840,15 @@ public class DependencyCheckScanAgent { * * @param engine a dependency-check engine * @param outDirectory the directory to write the reports to + * @throw ScanAgentException thrown if there is an error generating the + * report */ - private void generateExternalReports(Engine engine, File outDirectory) { - DatabaseProperties prop = null; - try (CveDB cve = CveDB.getInstance()) { - prop = cve.getDatabaseProperties(); - } catch (DatabaseException ex) { - //TODO shouldn't this be a fatal exception - LOGGER.debug("Unable to retrieve DB Properties", ex); - } - final ReportGenerator r = new ReportGenerator(this.applicationName, engine.getDependencies(), engine.getAnalyzers(), prop); + private void generateExternalReports(Engine engine, File outDirectory) throws ScanAgentException { try { - r.generateReports(outDirectory.getCanonicalPath(), this.reportFormat.name()); - } catch (IOException | ReportException ex) { - LOGGER.error("Unexpected exception occurred during analysis; please see the verbose error log for more details."); - LOGGER.debug("", ex); + engine.writeReports(applicationName, outDirectory, this.reportFormat.name()); + } catch (ReportException ex) { + LOGGER.debug("Unexpected exception occurred during analysis; please see the verbose error log for more details.", ex); + throw new ScanAgentException("Error generating the report", ex); } } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/reporting/ReportGenerator.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/reporting/ReportGenerator.java index b8acd2557..8b1229a98 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/reporting/ReportGenerator.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/reporting/ReportGenerator.java @@ -107,29 +107,8 @@ public class ReportGenerator { */ public ReportGenerator(String applicationName, List dependencies, List analyzers, DatabaseProperties properties) { velocityEngine = createVelocityEngine(); - context = createContext(); - velocityEngine.init(); - final EscapeTool enc = new EscapeTool(); - - final DateTime dt = new DateTime(); - final DateTimeFormatter dateFormat = DateTimeFormat.forPattern("MMM d, yyyy 'at' HH:mm:ss z"); - final DateTimeFormatter dateFormatXML = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); - -// final Date d = new Date(); -// final DateFormat dateFormat = new SimpleDateFormat("MMM d, yyyy 'at' HH:mm:ss z"); -// final DateFormat dateFormatXML = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); - final String scanDate = dateFormat.print(dt); - final String scanDateXML = dateFormatXML.print(dt); - - context.put("applicationName", applicationName); - context.put("dependencies", dependencies); - context.put("analyzers", analyzers); - context.put("properties", properties); - context.put("scanDate", scanDate); - context.put("scanDateXML", scanDateXML); - context.put("enc", enc); - context.put("version", Settings.getString(Settings.KEYS.APPLICATION_VERSION, "Unknown")); + context = createContext(applicationName, dependencies, analyzers, properties); } /** @@ -148,9 +127,15 @@ public class ReportGenerator { List dependencies, List analyzers, DatabaseProperties properties) { this(applicationName, dependencies, analyzers, properties); - context.put("applicationVersion", version); - context.put("artifactID", artifactID); - context.put("groupID", groupID); + if (version != null) { + context.put("applicationVersion", version); + } + if (artifactID != null) { + context.put("artifactID", artifactID); + } + if (groupID != null) { + context.put("groupID", groupID); + } } /** @@ -166,67 +151,235 @@ public class ReportGenerator { } /** - * Creates a new Velocity Context. + * Constructs the velocity context used to generate the dependency-check + * reports. * - * @return a Velocity Context + * @param applicationName the application name being analyzed + * @param dependencies the list of dependencies + * @param analyzers the list of analyzers used + * @param properties the database properties (containing timestamps of the + * NVD CVE data) + * @return the velocity context */ - private Context createContext() { - return new VelocityContext(); + private VelocityContext createContext(String applicationName, List dependencies, List analyzers, DatabaseProperties properties) { + final DateTime dt = new DateTime(); + final DateTimeFormatter dateFormat = DateTimeFormat.forPattern("MMM d, yyyy 'at' HH:mm:ss z"); + final DateTimeFormatter dateFormatXML = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); + + final String scanDate = dateFormat.print(dt); + final String scanDateXML = dateFormatXML.print(dt); + + VelocityContext ctxt = new VelocityContext(); + ctxt.put("applicationName", applicationName); + ctxt.put("dependencies", dependencies); + ctxt.put("analyzers", analyzers); + ctxt.put("properties", properties); + ctxt.put("scanDate", scanDate); + ctxt.put("scanDateXML", scanDateXML); + ctxt.put("enc", new EscapeTool()); + ctxt.put("version", Settings.getString(Settings.KEYS.APPLICATION_VERSION, "Unknown")); + return ctxt; } /** - * Generates the Dependency Reports for the identified dependencies. + * Writes the dependency-check report to the given output location. * - * @param outputStream the OutputStream to send the generated report to - * @param format the format the report should be written in - * @throws IOException is thrown when the template file does not exist - * @throws Exception is thrown if there is an error writing out the reports - */ - public void generateReports(OutputStream outputStream, Format format) throws IOException, Exception { - if (format == Format.XML || format == Format.ALL) { - generateReport("XmlReport", outputStream); - } - if (format == Format.HTML || format == Format.ALL) { - generateReport("HtmlReport", outputStream); - } - if (format == Format.VULN || format == Format.ALL) { - generateReport("VulnerabilityReport", outputStream); - } - if (format == Format.JSON || format == Format.ALL) { - generateReport("JsonReport", outputStream); - } - if (format == Format.CSV || format == Format.ALL) { - generateReport("CsvReport", outputStream); - } - } - - /** - * Generates the Dependency Reports for the identified dependencies. - * - * @param outputDir the path where the reports should be written - * @param format the format the report should be written in - * @throws ReportException is thrown if there is an error writing out the + * @param outputLocation the path where the reports should be written + * @param format the format the report should be written in (XML, HTML, + * JSON, CSV, ALL) or even the path to a custom velocity template (either + * fully qualified or the template name on the class path). + * @throws ReportException is thrown if there is an error creating out the * reports */ - public void generateReports(String outputDir, Format format) throws ReportException { - if (format == Format.XML || format == Format.ALL) { - generateReport("XmlReport", outputDir + File.separator + "dependency-check-report.xml"); + public void write(String outputLocation, String format) throws ReportException { + Format reportFormat = null; + try { + reportFormat = Format.valueOf(format.toUpperCase()); + } catch (IllegalArgumentException ex) { + LOGGER.trace("ignore this exception", ex); } - if (format == Format.JSON || format == Format.ALL) { - generateReport("JsonReport", outputDir + File.separator + "dependency-check-report.json"); - pretifyJson(outputDir + File.separator + "dependency-check-report.json"); + + if (reportFormat != null) { + write(outputLocation, reportFormat); + } else { + File out = getReportFile(outputLocation, null); + if (out.isDirectory()) { + throw new ReportException("Unable to write non-standard VSL output to a directory, please specify a file name"); + } + processTemplate(format, out); } - if (format == Format.CSV || format == Format.ALL) { - generateReport("CsvReport", outputDir + File.separator + "dependency-check-report.csv"); - } - if (format == Format.HTML || format == Format.ALL) { - generateReport("HtmlReport", outputDir + File.separator + "dependency-check-report.html"); - } - if (format == Format.VULN || format == Format.ALL) { - generateReport("VulnerabilityReport", outputDir + File.separator + "dependency-check-vulnerability.html"); + + } + + /** + * Writes the dependency-check report(s). + * + * @param outputLocation the path where the reports should be written + * @param format the format the report should be written in (XML, HTML, ALL) + * @throws ReportException is thrown if there is an error creating out the + * reports + */ + public void write(String outputLocation, Format format) throws ReportException { + if (format == Format.ALL) { + for (Format f : Format.values()) { + if (f != Format.ALL) { + write(outputLocation, f); + } + } + } else { + final File out = getReportFile(outputLocation, format); + final String templateName = format.toString().toLowerCase() + "Report"; + processTemplate(templateName, out); + if (format == Format.JSON) { + pretifyJson(out.getPath()); + } } } +// /** +// * Writes the dependency-check report(s). +// * +// * @param outputStream the OutputStream to send the generated report to +// * @param format the format the report should be written in +// * @throws ReportException thrown if the report format is ALL +// * @throws IOException is thrown when the template file does not exist +// * @throws Exception is thrown if there is an error writing out the reports +// */ +// public void write(OutputStream outputStream, Format format) throws ReportException, IOException, Exception { +// if (format == Format.ALL) { +// throw new ReportException("Unable to write ALL reports to a single output stream, please check the API"); +// } +// final String templateName = format.toString().toLowerCase() + "Report"; +// processTemplate(templateName, outputStream); +// } + + /** + * Determines the report file name based on the give output location and + * format. If the output location contains a full file name that has the + * correct extension for the given report type then the output location is + * returned. However, if the output location is a directory, this method + * will generate the correct name for the given output format. + * + * @param outputLocation the specified output location + * @param format the report format + * @return the report File + */ + protected File getReportFile(String outputLocation, Format format) { + File outFile = new File(outputLocation); + if (outFile.getParentFile() == null) { + outFile = new File(".", outputLocation); + } + final String pathToCheck = outputLocation.toLowerCase(); + if (format == Format.XML && !pathToCheck.endsWith(".xml")) { + return new File(outFile, "dependency-check-report.xml"); + } + if (format == Format.HTML && !pathToCheck.endsWith(".html") && !pathToCheck.endsWith(".htm")) { + return new File(outFile, "dependency-check-report.html"); + } + if (format == Format.VULN && !pathToCheck.endsWith(".html") && !pathToCheck.endsWith(".htm")) { + return new File(outFile, "dependency-check-vulnerability.html"); + } + if (format == Format.JSON && !pathToCheck.endsWith(".json")) { + return new File(outFile, "dependency-check-report.json"); + } + if (format == Format.CSV && !pathToCheck.endsWith(".csv")) { + return new File(outFile, "dependency-check-report.csv"); + } + return outFile; + } + + /** + * Generates a report from a given Velocity Template. The template name + * provided can be the name of a template contained in the jar file, such as + * 'XmlReport' or 'HtmlReport', or the template name can be the path to a + * template file. + * + * @param template the name of the template to load + * @param file the output file to write the report to + * @throws ReportException is thrown when the report cannot be generated + */ + protected void processTemplate(String template, File file) throws ReportException { + ensureParentDirectoryExists(file); + try (OutputStream output = new FileOutputStream(file)) { + processTemplate(template, output); + } catch (IOException ex) { + throw new ReportException(String.format("Unable to write to file: %s", file), ex); + } + } + + /** + * Generates a report from a given Velocity Template. The template name + * provided can be the name of a template contained in the jar file, such as + * 'XmlReport' or 'HtmlReport', or the template name can be the path to a + * template file. + * + * @param templateName the name of the template to load + * @param outputStream the OutputStream to write the report to + * @throws ReportException is thrown when an exception occurs + */ + protected void processTemplate(String templateName, OutputStream outputStream) throws ReportException { + InputStream input = null; + String logTag = null; + final File f = new File(templateName); + try { + if (f.isFile()) { + try { + logTag = templateName; + input = new FileInputStream(f); + } catch (FileNotFoundException ex) { + throw new ReportException("Unable to locate template file: " + templateName, ex); + } + } else { + logTag = "templates/" + templateName + ".vsl"; + input = this.getClass().getClassLoader().getResourceAsStream(logTag); + } + if (input == null) { + logTag = templateName; + input = this.getClass().getClassLoader().getResourceAsStream(templateName); + } + if (input == null) { + throw new ReportException("Template file doesn't exist: " + logTag); + } + + try (InputStreamReader reader = new InputStreamReader(input, "UTF-8"); + OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8")) { + if (!velocityEngine.evaluate(context, writer, logTag, reader)) { + throw new ReportException("Failed to convert the template into html."); + } + writer.flush(); + } catch (UnsupportedEncodingException ex) { + throw new ReportException("Unable to generate the report using UTF-8", ex); + } catch (IOException ex) { + throw new ReportException("Unable to write the report", ex); + } + } finally { + if (input != null) { + try { + input.close(); + } catch (IOException ex) { + LOGGER.trace("Error closing input", ex); + } + } + } + } + /** + * Validates that the given file's parent directory exists. If the directory + * does not exist an attempt to create the necessary path is made; if that + * fails a ReportException will be raised. + * + * @param file the file or directory directory + * @throws ReportException thrown if the parent directory does not exist and + * cannot be created + */ + private void ensureParentDirectoryExists(File file) throws ReportException { + if (!file.getParentFile().exists()) { + final boolean created = file.getParentFile().mkdirs(); + if (!created) { + final String msg = String.format("Unable to create directory '%s'.", file.getParentFile().getAbsolutePath()); + throw new ReportException(msg); + } + } + } /** * Reformats the given JSON file. * @@ -311,139 +464,4 @@ public class ReportGenerator { } } } - - /** - * Generates the Dependency Reports for the identified dependencies. - * - * @param outputDir the path where the reports should be written - * @param outputFormat the format the report should be written in (XML, - * HTML, ALL) - * @throws ReportException is thrown if there is an error creating out the - * reports - */ - public void generateReports(String outputDir, String outputFormat) throws ReportException { - final String format = outputFormat.toUpperCase(); - final String pathToCheck = outputDir.toLowerCase(); - if (format.matches("^(XML|HTML|VULN|JSON|ALL)$")) { - if ("XML".equalsIgnoreCase(format)) { - if (pathToCheck.endsWith(".xml")) { - generateReport("XmlReport", outputDir); - } else { - generateReports(outputDir, Format.XML); - } - } - if ("HTML".equalsIgnoreCase(format)) { - if (pathToCheck.endsWith(".html") || pathToCheck.endsWith(".htm")) { - generateReport("HtmlReport", outputDir); - } else { - generateReports(outputDir, Format.HTML); - } - } - if ("VULN".equalsIgnoreCase(format)) { - if (pathToCheck.endsWith(".html") || pathToCheck.endsWith(".htm")) { - generateReport("VulnReport", outputDir); - } else { - generateReports(outputDir, Format.VULN); - } - } - if ("JSON".equalsIgnoreCase(format)) { - if (pathToCheck.endsWith(".json")) { - generateReport("JsonReport", outputDir); - pretifyJson(outputDir); - } else { - generateReports(outputDir, Format.JSON); - } - } - if ("CSV".equalsIgnoreCase(format)) { - if (pathToCheck.endsWith(".csv")) { - generateReport("CsvReport", outputDir); - } else { - generateReports(outputDir, Format.JSON); - } - } - if ("ALL".equalsIgnoreCase(format)) { - generateReports(outputDir, Format.ALL); - } - } - } - - /** - * Generates a report from a given Velocity Template. The template name - * provided can be the name of a template contained in the jar file, such as - * 'XmlReport' or 'HtmlReport', or the template name can be the path to a - * template file. - * - * @param templateName the name of the template to load - * @param outputStream the OutputStream to write the report to - * @throws ReportException is thrown when an exception occurs - */ - protected void generateReport(String templateName, OutputStream outputStream) throws ReportException { - InputStream input = null; - String templatePath = null; - final File f = new File(templateName); - try { - if (f.exists() && f.isFile()) { - try { - templatePath = templateName; - input = new FileInputStream(f); - } catch (FileNotFoundException ex) { - throw new ReportException("Unable to locate template file: " + templateName, ex); - } - } else { - templatePath = "templates/" + templateName + ".vsl"; - input = this.getClass().getClassLoader().getResourceAsStream(templatePath); - } - if (input == null) { - throw new ReportException("Template file doesn't exist: " + templatePath); - } - - try (InputStreamReader reader = new InputStreamReader(input, "UTF-8"); - OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8")) { - if (!velocityEngine.evaluate(context, writer, templatePath, reader)) { - throw new ReportException("Failed to convert the template into html."); - } - writer.flush(); - } catch (UnsupportedEncodingException ex) { - throw new ReportException("Unable to generate the report using UTF-8", ex); - } catch (IOException ex) { - throw new ReportException("Unable to write the report", ex); - } - } finally { - if (input != null) { - try { - input.close(); - } catch (IOException ex) { - LOGGER.trace("Error closing input", ex); - } - } - } - } - - /** - * Generates a report from a given Velocity Template. The template name - * provided can be the name of a template contained in the jar file, such as - * 'XmlReport' or 'HtmlReport', or the template name can be the path to a - * template file. - * - * @param templateName the name of the template to load - * @param outFileName the filename and path to write the report to - * @throws ReportException is thrown when the report cannot be generated - */ - protected void generateReport(String templateName, String outFileName) throws ReportException { - File outFile = new File(outFileName); - if (outFile.getParentFile() == null) { - outFile = new File(".", outFileName); - } - if (!outFile.getParentFile().exists()) { - final boolean created = outFile.getParentFile().mkdirs(); - if (!created) { - throw new ReportException("Unable to create directory '" + outFile.getParentFile().getAbsolutePath() + "'."); - } - } - try (OutputStream outputSteam = new FileOutputStream(outFile)) { - generateReport(templateName, outputSteam); - } catch (IOException ex) { - throw new ReportException("Unable to write to file: " + outFile, ex); - } - } } diff --git a/dependency-check-core/src/main/resources/templates/CsvReport.vsl b/dependency-check-core/src/main/resources/templates/csvReport.vsl similarity index 100% rename from dependency-check-core/src/main/resources/templates/CsvReport.vsl rename to dependency-check-core/src/main/resources/templates/csvReport.vsl diff --git a/dependency-check-core/src/main/resources/templates/HtmlReport.vsl b/dependency-check-core/src/main/resources/templates/htmlReport.vsl similarity index 100% rename from dependency-check-core/src/main/resources/templates/HtmlReport.vsl rename to dependency-check-core/src/main/resources/templates/htmlReport.vsl diff --git a/dependency-check-core/src/main/resources/templates/JsonReport.vsl b/dependency-check-core/src/main/resources/templates/jsonReport.vsl similarity index 100% rename from dependency-check-core/src/main/resources/templates/JsonReport.vsl rename to dependency-check-core/src/main/resources/templates/jsonReport.vsl diff --git a/dependency-check-core/src/main/resources/templates/VulnerabilityReport.vsl b/dependency-check-core/src/main/resources/templates/vulnReport.vsl similarity index 100% rename from dependency-check-core/src/main/resources/templates/VulnerabilityReport.vsl rename to dependency-check-core/src/main/resources/templates/vulnReport.vsl diff --git a/dependency-check-core/src/main/resources/templates/XmlReport.vsl b/dependency-check-core/src/main/resources/templates/xmlReport.vsl similarity index 100% rename from dependency-check-core/src/main/resources/templates/XmlReport.vsl rename to dependency-check-core/src/main/resources/templates/xmlReport.vsl diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineIT.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineIT.java index dd81bf828..a85d34793 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineIT.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineIT.java @@ -17,6 +17,7 @@ */ package org.owasp.dependencycheck; +import java.io.File; import java.io.IOException; import static org.junit.Assert.assertTrue; @@ -72,12 +73,7 @@ public class EngineIT extends BaseDBTestCase { throw ex; } } - DatabaseProperties prop = null; - try (CveDB cve = CveDB.getInstance()) { - prop = cve.getDatabaseProperties(); - } - ReportGenerator rg = new ReportGenerator("DependencyCheck", instance.getDependencies(), instance.getAnalyzers(), prop); - rg.generateReports("./target/", "ALL"); + instance.writeReports("dependency-check sample", new File("./target/"), "ALL"); instance.cleanup(); } } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIT.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIT.java index e472c1e63..c0392df31 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIT.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIT.java @@ -25,15 +25,12 @@ import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; -import static org.junit.Assert.fail; import org.junit.Test; import org.owasp.dependencycheck.BaseDBTestCase; import org.owasp.dependencycheck.BaseTest; import org.owasp.dependencycheck.Engine; -import org.owasp.dependencycheck.data.nvdcve.CveDB; import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; import org.owasp.dependencycheck.exception.ExceptionCollection; import org.owasp.dependencycheck.exception.ReportException; import org.owasp.dependencycheck.utils.InvalidSettingException; @@ -47,67 +44,6 @@ import static org.junit.Assert.fail; */ public class ReportGeneratorIT extends BaseDBTestCase { - /** - * Test of generateReport method, of class ReportGenerator. - * - * @throws Exception is thrown when an exception occurs. - */ - @Test - public void testGenerateReport() throws Exception { -// String templateName = "HtmlReport"; -// File f = new File("target/test-reports"); -// if (!f.exists()) { -// f.mkdir(); -// } -// String writeTo = "target/test-reports/Report.html"; -// Map properties = new HashMap(); -// Dependency d = new Dependency(); -// d.setFileName("FileName.jar"); -// d.setActualFilePath("lib/FileName.jar"); -// d.addCPEentry("cpe://a:/some:cpe:1.0"); -// -// List dependencies = new ArrayList(); -// d.getProductEvidence().addEvidence("jar","filename","test", Confidence.HIGH); -// d.getProductEvidence().addEvidence("manifest","vendor","test", Confidence.HIGH); -// -// for (Evidence e : d.getProductEvidence().iterator(Confidence.HIGH)) { -// String t = e.getValue(); -// } -// dependencies.add(d); -// -// Dependency d2 = new Dependency(); -// d2.setFileName("Another.jar"); -// d2.setActualFilePath("lib/Another.jar"); -// d2.addCPEentry("cpe://a:/another:cpe:1.0"); -// d2.addCPEentry("cpe://a:/another:cpe:1.1"); -// d2.addCPEentry("cpe://a:/another:cpe:1.2"); -// d2.getProductEvidence().addEvidence("jar","filename","another.jar", Confidence.HIGH); -// d2.getProductEvidence().addEvidence("manifest","vendor","Company A", Confidence.MEDIUM); -// -// for (Evidence e : d2.getProductEvidence().iterator(Confidence.HIGH)) { -// String t = e.getValue(); -// } -// -// dependencies.add(d2); -// -// Dependency d3 = new Dependency(); -// d3.setFileName("Third.jar"); -// d3.setActualFilePath("lib/Third.jar"); -// d3.getProductEvidence().addEvidence("jar","filename","third.jar", Confidence.HIGH); -// -// for (Evidence e : d3.getProductEvidence().iterator(Confidence.HIGH)) { -// String t = e.getValue(); -// } -// -// dependencies.add(d3); -// -// properties.put("dependencies",dependencies); -// -// ReportGenerator instance = new ReportGenerator(); -// instance.generateReport(templateName, writeTo, properties); - //assertTrue("need to add a real check here", false); - } - /** * Generates an XML report containing known vulnerabilities and realistic * data and validates the generated XML document against the XSD. @@ -115,7 +51,7 @@ public class ReportGeneratorIT extends BaseDBTestCase { * @throws Exception */ @Test - public void testGenerateXMLReport() { + public void testGenerateReport() { try { String templateName = "XmlReport"; @@ -123,7 +59,7 @@ public class ReportGeneratorIT extends BaseDBTestCase { if (!f.exists()) { f.mkdir(); } - String writeTo = "target/test-reports/Report.xml"; + File writeTo = new File("target/test-reports/Report.xml"); File suppressionFile = BaseTest.getResourceAsFile(this, "incorrectSuppressions.xml"); Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppressionFile.getAbsolutePath()); @@ -135,29 +71,20 @@ public class ReportGeneratorIT extends BaseDBTestCase { //File jetty = new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath()); File jetty = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar"); - boolean autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); Engine engine = new Engine(); - Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); engine.scan(struts); engine.scan(axis); engine.scan(jetty); engine.analyzeDependencies(); - - CveDB cveDB = CveDB.getInstance(); - DatabaseProperties dbProp = cveDB.getDatabaseProperties(); - - ReportGenerator generator = new ReportGenerator("Test Report", "org.owasp", "dependency-check-core", "1.4.7", - engine.getDependencies(), engine.getAnalyzers(), dbProp); - generator.generateReport(templateName, writeTo); - cveDB.close(); + engine.writeReports("Test Report", "org.owasp", "dependency-check-core", "1.4.7", writeTo, "XML"); engine.cleanup(); InputStream xsdStream = ReportGenerator.class.getClassLoader().getResourceAsStream("schema/dependency-check.1.5.xsd"); StreamSource xsdSource = new StreamSource(xsdStream); - StreamSource xmlSource = new StreamSource(new File(writeTo)); + StreamSource xmlSource = new StreamSource(writeTo); SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); Schema schema = sf.newSchema(xsdSource); Validator validator = schema.newValidator(); diff --git a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/AggregateMojo.java b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/AggregateMojo.java index 62c333efe..7a0c0b6d5 100644 --- a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/AggregateMojo.java +++ b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/AggregateMojo.java @@ -123,7 +123,8 @@ public class AggregateMojo extends BaseDependencyCheckMojo { outputDir = new File(this.getProject().getBuild().getDirectory()); } try { - writeReports(engine, this.getProject(), outputDir); + final MavenProject p = this.getProject(); + engine.writeReports(p.getName(), p.getGroupId(), p.getArtifactId(), p.getVersion(), outputDir, getFormat()); } catch (ReportException ex) { if (exCol == null) { exCol = new ExceptionCollection("Error writing aggregate report", ex); diff --git a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java index 99b3a401f..e7cf5f937 100644 --- a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java +++ b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java @@ -1069,35 +1069,6 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma return format; } - /** - * Generates the reports for a given dependency-check engine. - * - * @param engine a dependency-check engine - * @param p the Maven project - * @param outputDir the directory path to write the report(s) - * @throws ReportException thrown if there is an error writing the report - */ - protected void writeReports(Engine engine, MavenProject p, File outputDir) throws ReportException { - DatabaseProperties prop = null; - try (CveDB cve = CveDB.getInstance()) { - prop = cve.getDatabaseProperties(); - } catch (DatabaseException ex) { - //TODO shouldn't this throw an exception? - if (getLog().isDebugEnabled()) { - getLog().debug("Unable to retrieve DB Properties", ex); - } - } - final ReportGenerator r = new ReportGenerator(p.getName(), p.getGroupId(), p.getArtifactId(), p.getVersion(), - engine.getDependencies(), engine.getAnalyzers(), prop); - try { - r.generateReports(outputDir.getAbsolutePath(), format); - } catch (ReportException ex) { - final String msg = String.format("Error generating the report for %s", p.getName()); - throw new ReportException(msg, ex); - } - - } - // /** * Checks to see if a vulnerability has been identified with a CVSS score diff --git a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/CheckMojo.java b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/CheckMojo.java index cb95628db..1b6a30d55 100644 --- a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/CheckMojo.java +++ b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/CheckMojo.java @@ -25,6 +25,7 @@ import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.project.MavenProject; import org.owasp.dependencycheck.Engine; import org.owasp.dependencycheck.data.nvdcve.DatabaseException; import org.owasp.dependencycheck.exception.ExceptionCollection; @@ -99,19 +100,19 @@ public class CheckMojo extends BaseDependencyCheckMojo { ExceptionCollection exCol = scanArtifacts(getProject(), engine); if (engine.getDependencies().isEmpty()) { getLog().info("No dependencies were identified that could be analyzed by dependency-check"); - } else { - try { - engine.analyzeDependencies(); - } catch (ExceptionCollection ex) { - if (this.isFailOnError() && ex.isFatal()) { - throw new MojoExecutionException("One or more exceptions occurred during analysis", ex); - } - exCol = ex; + } + try { + engine.analyzeDependencies(); + } catch (ExceptionCollection ex) { + if (this.isFailOnError() && ex.isFatal()) { + throw new MojoExecutionException("One or more exceptions occurred during analysis", ex); } + exCol = ex; } if (exCol == null || !exCol.isFatal()) { try { - writeReports(engine, getProject(), getCorrectOutputDirectory()); + final MavenProject p = this.getProject(); + engine.writeReports(p.getName(), p.getGroupId(), p.getArtifactId(), p.getVersion(), getCorrectOutputDirectory(), getFormat()); } catch (ReportException ex) { if (this.isFailOnError()) { if (exCol != null) { From e86225c1e105b7374450ff971213da9a8ee7ba55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0est=C3=A1k=20V=C3=ADt?= Date: Wed, 24 May 2017 09:24:40 +0200 Subject: [PATCH 06/23] Added some caching for CveDB in order to speedup some scans --- .../dependencycheck/data/nvdcve/CveDB.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java index 7b42d82c3..a1430d28d 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java @@ -36,6 +36,7 @@ import java.util.Properties; import java.util.ResourceBundle; import java.util.Set; import javax.annotation.concurrent.ThreadSafe; +import org.apache.commons.collections.map.ReferenceMap; import org.owasp.dependencycheck.data.cwe.CweDB; import org.owasp.dependencycheck.dependency.Reference; import org.owasp.dependencycheck.dependency.Vulnerability; @@ -48,6 +49,8 @@ import org.owasp.dependencycheck.utils.Settings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static org.apache.commons.collections.map.AbstractReferenceMap.HARD; +import static org.apache.commons.collections.map.AbstractReferenceMap.SOFT; import static org.owasp.dependencycheck.data.nvdcve.CveDB.PreparedStatementCveDb.*; /** @@ -91,6 +94,9 @@ public final class CveDB implements AutoCloseable { */ private final EnumMap preparedStatements = new EnumMap<>(PreparedStatementCveDb.class); + @SuppressWarnings("unchecked") + private final Map> vulnerabilitiesForCpeCache = new ReferenceMap(HARD, SOFT); + /** * The enum value names must match the keys of the statements in the * statement bundles "dbStatements*.properties". @@ -265,6 +271,7 @@ public final class CveDB implements AutoCloseable { */ @Override public synchronized void close() { + clearCache(); if (instance != null) { instance.usageCount -= 1; if (instance.usageCount <= 0 && instance.isOpen()) { @@ -474,6 +481,7 @@ public final class CveDB implements AutoCloseable { * @param value the property value */ public synchronized void saveProperty(String key, String value) { + clearCache(); try { try { final PreparedStatement mergeProperty = getPreparedStatement(MERGE_PROPERTY); @@ -498,6 +506,17 @@ public final class CveDB implements AutoCloseable { } } + /** + * Clears cache. Should be called whenever something is modified. While this is not the optimal cache eviction + * strategy, this is good enough for typical usage (update DB and then only read) and it is easier to maintain + * the code. + * + * It should be also called when DB is closed. + */ + private void clearCache() { + vulnerabilitiesForCpeCache.clear(); + } + /** * Retrieves the vulnerabilities associated with the specified CPE. * @@ -506,6 +525,13 @@ public final class CveDB implements AutoCloseable { * @throws DatabaseException thrown if there is an exception retrieving data */ public synchronized List getVulnerabilities(String cpeStr) throws DatabaseException { + final List cachedVulnerabilities = vulnerabilitiesForCpeCache.get(cpeStr); + if (cachedVulnerabilities != null) { + LOGGER.debug("Cache hit for {}", cpeStr); + return cachedVulnerabilities; + } else { + LOGGER.debug("Cache miss for {}", cpeStr); + } final VulnerableSoftware cpe = new VulnerableSoftware(); try { cpe.parseName(cpeStr); @@ -554,6 +580,7 @@ public final class CveDB implements AutoCloseable { } finally { DBUtils.closeResultSet(rs); } + vulnerabilitiesForCpeCache.put(cpeStr, vulnerabilities); return vulnerabilities; } @@ -633,6 +660,7 @@ public final class CveDB implements AutoCloseable { * @throws DatabaseException is thrown if the database */ public synchronized void updateVulnerability(Vulnerability vuln) throws DatabaseException { + clearCache(); try { int vulnerabilityId = 0; final PreparedStatement selectVulnerabilityId = getPreparedStatement(SELECT_VULNERABILITY_ID); @@ -799,6 +827,7 @@ public final class CveDB implements AutoCloseable { * ensure orphan entries are removed. */ public synchronized void cleanupDatabase() { + clearCache(); try { final PreparedStatement ps = getPreparedStatement(CLEANUP_ORPHANS); if (ps != null) { @@ -934,6 +963,7 @@ public final class CveDB implements AutoCloseable { * Deletes unused dictionary entries from the database. */ public synchronized void deleteUnusedCpe() { + clearCache(); PreparedStatement ps = null; try { ps = connection.prepareStatement(statementBundle.getString("DELETE_UNUSED_DICT_CPE")); @@ -956,6 +986,7 @@ public final class CveDB implements AutoCloseable { * @param product the CPE product */ public synchronized void addCpe(String cpe, String vendor, String product) { + clearCache(); PreparedStatement ps = null; try { ps = connection.prepareStatement(statementBundle.getString("ADD_DICT_CPE")); From 3bdc6988b3a36e1bbace057f8dc1d8b726d39a8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0est=C3=A1k=20V=C3=ADt?= Date: Wed, 24 May 2017 16:00:37 +0200 Subject: [PATCH 07/23] Minor adjustments of caching for CveDB, based on code review --- .../java/org/owasp/dependencycheck/data/nvdcve/CveDB.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java index a1430d28d..4fe5ad951 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java @@ -24,6 +24,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Collections; import java.util.EnumMap; import java.util.HashMap; import java.util.HashSet; @@ -95,7 +96,7 @@ public final class CveDB implements AutoCloseable { private final EnumMap preparedStatements = new EnumMap<>(PreparedStatementCveDb.class); @SuppressWarnings("unchecked") - private final Map> vulnerabilitiesForCpeCache = new ReferenceMap(HARD, SOFT); + private final Map> vulnerabilitiesForCpeCache = Collections.synchronizedMap(new ReferenceMap(HARD, SOFT)); /** * The enum value names must match the keys of the statements in the @@ -271,11 +272,11 @@ public final class CveDB implements AutoCloseable { */ @Override public synchronized void close() { - clearCache(); if (instance != null) { instance.usageCount -= 1; if (instance.usageCount <= 0 && instance.isOpen()) { instance.usageCount = 0; + clearCache(); instance.closeStatements(); try { instance.connection.close(); From 986ad0584d9912b5de6eee6e0afc143cc45d75d2 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Thu, 25 May 2017 07:50:10 -0400 Subject: [PATCH 08/23] updated packaging --- build-reporting/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/build-reporting/pom.xml b/build-reporting/pom.xml index d77663e2d..8b99ce422 100644 --- a/build-reporting/pom.xml +++ b/build-reporting/pom.xml @@ -24,6 +24,7 @@ Copyright (c) 2017 - Jeremy Long. All Rights Reserved. build-reporting + pom From e411c03e7fa899f6eaa96d05184e6bc1e22c9f9c Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 27 May 2017 11:10:14 -0400 Subject: [PATCH 09/23] updates for issue #743 and #746 --- .../dependencycheck-base-suppression.xml | 43 +++++++++++++------ 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml b/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml index a4d0c1d32..e210335ca 100644 --- a/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml +++ b/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml @@ -1,19 +1,19 @@ - - .*Microsoft\.VisualStudio\.QualityTools\.UnitTestFramework*\.dll - CVE-2014-3802 + .*Microsoft\.VisualStudio\.QualityTools\.UnitTestFramework*\.dll + CVE-2014-3802 - - .*EntityFramework\.SqlServer*\.dll - cpe:/a:microsoft:server:6.0.0.0 - cpe:/a:microsoft:sql_server:6.0 + .*EntityFramework\.SqlServer*\.dll + cpe:/a:microsoft:server:6.0.0.0 + cpe:/a:microsoft:sql_server:6.0 ^com\.splunk:splunk:.*$ cpe:/a:splunk:splunk - - + + ^org\.openid4java:openid4java:.*$ cpe:/a:openid:openid cpe:/a:openid:openid4java - - + + ^org\.springframework\.cloud:spring-cloud-netflix-core:.*$ cpe:/a:pivotal:spring_framework cpe:/a:pivotal_software:spring_framework - - + + @@ -607,5 +607,20 @@ cpe:/a:pivotal:spring_framework cpe:/a:pivotal_software:spring_framework cpe:/a:context_project:context - + + + + ^com\.artofsolving:jodconverter:.*$ + cpe:/a:openoffice:openoffice.org + cpe:/a:openoffice:openoffice + + + + ^org\.xerial:sqlite-jdbc:.*$ + CVE-2015-3717 + From 576e26144d1f0a39dfd929468f5a1018260cdde9 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 27 May 2017 12:05:08 -0400 Subject: [PATCH 10/23] updated version --- build-reporting/pom.xml | 2 +- dependency-check-ant/pom.xml | 2 +- dependency-check-cli/pom.xml | 2 +- dependency-check-core/pom.xml | 2 +- dependency-check-maven/pom.xml | 2 +- dependency-check-plugin/pom.xml | 2 +- dependency-check-utils/pom.xml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build-reporting/pom.xml b/build-reporting/pom.xml index 8b99ce422..36200f599 100644 --- a/build-reporting/pom.xml +++ b/build-reporting/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2017 - Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 1.4.6-SNAPSHOT + 2.0.0-SNAPSHOT build-reporting diff --git a/dependency-check-ant/pom.xml b/dependency-check-ant/pom.xml index 9c7962954..6cb92aaf7 100644 --- a/dependency-check-ant/pom.xml +++ b/dependency-check-ant/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 1.4.6-SNAPSHOT + 2.0.0-SNAPSHOT dependency-check-ant diff --git a/dependency-check-cli/pom.xml b/dependency-check-cli/pom.xml index a1d13d0c2..03529b9a6 100644 --- a/dependency-check-cli/pom.xml +++ b/dependency-check-cli/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 1.4.6-SNAPSHOT + 2.0.0-SNAPSHOT dependency-check-cli diff --git a/dependency-check-core/pom.xml b/dependency-check-core/pom.xml index 47db9f89c..3425e4a16 100644 --- a/dependency-check-core/pom.xml +++ b/dependency-check-core/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 1.4.6-SNAPSHOT + 2.0.0-SNAPSHOT dependency-check-core diff --git a/dependency-check-maven/pom.xml b/dependency-check-maven/pom.xml index 8f03b9bb0..edb89aa63 100644 --- a/dependency-check-maven/pom.xml +++ b/dependency-check-maven/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 1.4.6-SNAPSHOT + 2.0.0-SNAPSHOT dependency-check-maven maven-plugin diff --git a/dependency-check-plugin/pom.xml b/dependency-check-plugin/pom.xml index 0cccc8d97..b53f42ae4 100644 --- a/dependency-check-plugin/pom.xml +++ b/dependency-check-plugin/pom.xml @@ -21,7 +21,7 @@ Copyright (c) 2017 Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 1.4.6-SNAPSHOT + 2.0.0-SNAPSHOT org.owasp dependency-check-plugin diff --git a/dependency-check-utils/pom.xml b/dependency-check-utils/pom.xml index 035222a77..bc6577a0b 100644 --- a/dependency-check-utils/pom.xml +++ b/dependency-check-utils/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2014 - Jeremy Long. All Rights Reserved. org.owasp dependency-check-parent - 1.4.6-SNAPSHOT + 2.0.0-SNAPSHOT dependency-check-utils From d5df4920c70974c9243f30a3f3d6c40b47ba1c2d Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 27 May 2017 12:06:34 -0400 Subject: [PATCH 11/23] updated version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9b371cead..ed1919d21 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2012 - Jeremy Long org.owasp dependency-check-parent - 1.4.6-SNAPSHOT + 2.0.0-SNAPSHOT pom From 1b14c10085da2caa10c7138b911f547fd281dc2a Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 27 May 2017 12:06:49 -0400 Subject: [PATCH 12/23] checkstyle corrections --- .../src/main/java/org/owasp/dependencycheck/Engine.java | 2 +- .../dependencycheck/agent/DependencyCheckScanAgent.java | 3 --- .../java/org/owasp/dependencycheck/data/nvdcve/CveDB.java | 8 ++++++-- .../org/owasp/dependencycheck/reporting/EscapeTool.java | 4 ++-- .../owasp/dependencycheck/reporting/ReportGenerator.java | 4 ++-- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java index e50d625aa..6d7915e15 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java @@ -815,7 +815,7 @@ public class Engine implements FileFilter { public void writeReports(String applicationName, String groupId, String artifactId, String version, File outputDir, String format) throws ReportException { - DatabaseProperties prop = database.getDatabaseProperties(); + final DatabaseProperties prop = database.getDatabaseProperties(); final ReportGenerator r = new ReportGenerator(applicationName, groupId, artifactId, version, dependencies, getAnalyzers(), prop); try { r.write(outputDir.getAbsolutePath(), format); diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.java index c862d0fc1..e63c51214 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.java @@ -18,12 +18,9 @@ package org.owasp.dependencycheck.agent; import java.io.File; -import java.io.IOException; import java.util.List; import org.owasp.dependencycheck.Engine; -import org.owasp.dependencycheck.data.nvdcve.CveDB; import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; import org.owasp.dependencycheck.dependency.Dependency; import org.owasp.dependencycheck.dependency.Identifier; import org.owasp.dependencycheck.dependency.Vulnerability; diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java index 4fe5ad951..d88a25119 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java @@ -95,6 +95,9 @@ public final class CveDB implements AutoCloseable { */ private final EnumMap preparedStatements = new EnumMap<>(PreparedStatementCveDb.class); + /** + * Cache for CVE lookups; used to speed up the vulnerability search process. + */ @SuppressWarnings("unchecked") private final Map> vulnerabilitiesForCpeCache = Collections.synchronizedMap(new ReferenceMap(HARD, SOFT)); @@ -508,8 +511,9 @@ public final class CveDB implements AutoCloseable { } /** - * Clears cache. Should be called whenever something is modified. While this is not the optimal cache eviction - * strategy, this is good enough for typical usage (update DB and then only read) and it is easier to maintain + * Clears cache. Should be called whenever something is modified. While this + * is not the optimal cache eviction strategy, this is good enough for + * typical usage (update DB and then only read) and it is easier to maintain * the code. * * It should be also called when DB is closed. diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/reporting/EscapeTool.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/reporting/EscapeTool.java index 48014183a..4eb456176 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/reporting/EscapeTool.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/reporting/EscapeTool.java @@ -124,7 +124,7 @@ public class EscapeTool { return ""; } boolean addComma = false; - StringBuilder sb = new StringBuilder(); + final StringBuilder sb = new StringBuilder(); for (Identifier id : ids) { if (!"cpe".equals(id.getType())) { if (addComma) { @@ -150,7 +150,7 @@ public class EscapeTool { return ""; } boolean addComma = false; - StringBuilder sb = new StringBuilder(); + final StringBuilder sb = new StringBuilder(); for (Identifier id : ids) { if ("cpe".equals(id.getType())) { if (addComma) { diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/reporting/ReportGenerator.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/reporting/ReportGenerator.java index 8b1229a98..d31705519 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/reporting/ReportGenerator.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/reporting/ReportGenerator.java @@ -169,7 +169,7 @@ public class ReportGenerator { final String scanDate = dateFormat.print(dt); final String scanDateXML = dateFormatXML.print(dt); - VelocityContext ctxt = new VelocityContext(); + final VelocityContext ctxt = new VelocityContext(); ctxt.put("applicationName", applicationName); ctxt.put("dependencies", dependencies); ctxt.put("analyzers", analyzers); @@ -202,7 +202,7 @@ public class ReportGenerator { if (reportFormat != null) { write(outputLocation, reportFormat); } else { - File out = getReportFile(outputLocation, null); + final File out = getReportFile(outputLocation, null); if (out.isDirectory()) { throw new ReportException("Unable to write non-standard VSL output to a directory, please specify a file name"); } From 04e0b95a8a5a2a68dabb30ebedd2d71c71d864b9 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 27 May 2017 13:03:51 -0400 Subject: [PATCH 13/23] this is purely a reporting module - no need to deploy --- build-reporting/pom.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/build-reporting/pom.xml b/build-reporting/pom.xml index 36200f599..ae73355ef 100644 --- a/build-reporting/pom.xml +++ b/build-reporting/pom.xml @@ -63,6 +63,13 @@ Copyright (c) 2017 - Jeremy Long. All Rights Reserved. + + org.apache.maven.plugins + maven-deploy-plugin + + true + + org.jacoco jacoco-maven-plugin From 7956606876a72d482c5928a6abb226096e38f9f6 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sun, 28 May 2017 07:35:04 -0400 Subject: [PATCH 14/23] test case for #737 --- .../it/737-joda-time-issue/invoker.properties | 19 + .../src/it/737-joda-time-issue/pom.xml | 630 ++++++++++++++++++ .../it/737-joda-time-issue/postbuild.groovy | 31 + .../it/737-joda-time-issue/prebuild.groovy | 17 + 4 files changed, 697 insertions(+) create mode 100644 dependency-check-maven/src/it/737-joda-time-issue/invoker.properties create mode 100644 dependency-check-maven/src/it/737-joda-time-issue/pom.xml create mode 100644 dependency-check-maven/src/it/737-joda-time-issue/postbuild.groovy create mode 100644 dependency-check-maven/src/it/737-joda-time-issue/prebuild.groovy diff --git a/dependency-check-maven/src/it/737-joda-time-issue/invoker.properties b/dependency-check-maven/src/it/737-joda-time-issue/invoker.properties new file mode 100644 index 000000000..db025b28c --- /dev/null +++ b/dependency-check-maven/src/it/737-joda-time-issue/invoker.properties @@ -0,0 +1,19 @@ +# +# This file is part of dependency-check-maven. +# +# 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. +# +# Copyright (c) 2017 Jeremy Long. All Rights Reserved. +# + +invoker.goals = install -X ${project.groupId}:${project.artifactId}:${project.version}:check -DskipSystemScope=true -Dformat=JSON diff --git a/dependency-check-maven/src/it/737-joda-time-issue/pom.xml b/dependency-check-maven/src/it/737-joda-time-issue/pom.xml new file mode 100644 index 000000000..3b4baa359 --- /dev/null +++ b/dependency-check-maven/src/it/737-joda-time-issue/pom.xml @@ -0,0 +1,630 @@ + + + + + + + com.test + 4.0.0 + 1.0.9-SNAPSHOT + test pom parent + test-backend-app + test-backend web app + + + 1.8 + 1.8 + 1.8 + UTF-8 + @{project.version} + + **/test/app/resources/*,**/test/app/config/**/*,**/test/model/**/*,**/test/common/**/* + + ${maven.build.timestamp} + dd/MM/yyyy HH:mm:ss + + + -Xdoclint:none + + + 1.1.6 + 1.5.0.RELEASE + 8.0.41 + 3.0.1 + 4.3.6.RELEASE + 1.7.22 + 1.8.10 + 2.8.2 + 1.0.2 + 2.10.3 + + 3.5 + 1.10 + 4.1 + 1.5.1 + 1.3.2 + 2.5 + 1.5.10 + 1.1.3 + 1.16.12 + 1.1.0.Final + 1.0 + 2.23.2 + 5.2.4.Final + + + 4.12 + 1.10.19 + 1.6.6 + 3.6.1 + 1.2.5 + + + 3.0.1 + 3.5.1 + 2.6 + 2.5.3 + 1.10 + 2.10.4 + 3.0.0 + 3.0.2 + 2.7 + 1.0 + 0.7.4.201502262128 + 2.2.4 + 3.0.0 + + + + + + + + + joda-time + joda-time + 1.6 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-jersey + + + org.springframework.boot + spring-boot-starter-tomcat + + + org.springframework.boot + spring-boot-devtools + true + + + org.springframework.boot + spring-boot-actuator + + + org.springframework + spring-context-support + + + org.springframework.boot + spring-boot-loader + + + org.springframework.boot + spring-boot-starter-security + + + + + org.apache.tomcat.embed + tomcat-embed-core + + + org.apache.tomcat.embed + tomcat-embed-el + + + org.apache.tomcat.embed + tomcat-embed-logging-juli + + + org.apache.tomcat.embed + tomcat-embed-websocket + + + + + + org.mapstruct + mapstruct-jdk8 + + + + + + commons-io + commons-io + + + commons-fileupload + commons-fileupload + + + org.apache.commons + commons-lang3 + + + + + + org.glassfish.jersey.media + jersey-media-multipart + + + + + + io.swagger + swagger-jersey2-jaxrs + + + + + + org.slf4j + slf4j-api + + + org.slf4j + jcl-over-slf4j + + + org.slf4j + log4j-over-slf4j + + + org.slf4j + jul-to-slf4j + + + + + + net.sf.ehcache + ehcache + + + + + org.glassfish + javax.json + + + + + junit + junit + + + org.mockito + mockito-all + + + org.springframework + spring-test + + + org.powermock + powermock-api-mockito + + + org.powermock + powermock-module-junit4 + + + org.springframework.boot + spring-boot-starter-test + test + + + + + javax.json + javax.json-api + + + + + + + + + com.slimpay + hapiclient + ${com.slimpay.version} + + + + + org.springframework.boot + spring-boot-starter-jersey + ${spring.boot.version} + + + org.springframework.boot + spring-boot-starter-tomcat + ${spring.boot.version} + + + org.springframework.boot + spring-boot-starter-web + ${spring.boot.version} + + + org.springframework.boot + spring-boot-devtools + ${spring.boot.version} + + + org.springframework.boot + spring-boot-actuator + ${spring.boot.version} + + + org.springframework.boot + spring-boot-loader + ${spring.boot.version} + + + org.springframework.boot + spring-boot-starter-security + ${spring.boot.version} + + + org.springframework.boot + spring-boot-starter-test + ${spring.boot.version} + test + + + + + + org.springframework + spring-core + ${spring.framework.version} + + + + org.springframework + spring-context + ${spring.framework.version} + + + + org.springframework + spring-context-support + ${spring.framework.version} + + + + org.springframework + spring-aop + ${spring.framework.version} + + + + org.springframework + spring-beans + ${spring.framework.version} + + + + org.springframework + spring-web + ${spring.framework.version} + + + + org.springframework + spring-webmvc + ${spring.framework.version} + + + + org.springframework + spring-test + ${spring.framework.version} + + + + + + org.apache.tomcat.embed + tomcat-embed-core + ${tomcat.version} + + + org.apache.tomcat.embed + tomcat-embed-el + ${tomcat.version} + + + org.apache.tomcat.embed + tomcat-embed-logging-juli + ${tomcat.version} + + + org.apache.tomcat.embed + tomcat-embed-jasper + ${tomcat.version} + + + org.apache.tomcat.embed + tomcat-embed-websocket + ${tomcat.version} + + + + + + org.aspectj + aspectjrt + ${aspectj.version} + + + + org.aspectj + aspectjweaver + ${aspectj.version} + + + + + + net.sf.ehcache + ehcache + ${ehcache.version} + + + + + + org.glassfish.jersey.media + jersey-media-multipart + ${jersey.multipart.version} + + + + + org.glassfish + javax.json + 1.0.4 + + + + + + org.apache.commons + commons-lang3 + ${commons-lang.version} + + + + org.apache.commons + commons-collections4 + ${commons-collections.version} + + + + commons-validator + commons-validator + ${commons-validator.version} + + + + commons-codec + commons-codec + ${commons-codec.version} + + + + commons-fileupload + commons-fileupload + ${commons-fileupload.version} + + + + commons-io + commons-io + ${commons-io.version} + + + + javax.servlet + javax.servlet-api + ${servlet-api.version} + provided + + + + com.fasterxml.jackson.core + jackson-core + ${jackson.version} + + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-base + ${jackson.version} + + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-json-provider + ${jackson.version} + + + + io.swagger + swagger-jersey2-jaxrs + ${swagger.version} + + + + org.projectlombok + lombok + ${lombok.version} + provided + + + + org.mapstruct + mapstruct-jdk8 + ${mapstruct.version} + + + + javax.json + javax.json-api + ${javax.json.version} + + + + org.hibernate + hibernate-validator + ${org.hibernate.hibernate-validator.version} + + + + + + + org.slf4j + slf4j-api + ${slf4j.version} + + + + org.slf4j + jcl-over-slf4j + ${slf4j.version} + + + + org.slf4j + log4j-over-slf4j + ${slf4j.version} + + + + org.slf4j + jul-to-slf4j + ${slf4j.version} + + + + ch.qos.logback + logback-classic + ${logback.version} + + + + + + junit + junit + ${junit.version} + test + + + + org.mockito + mockito-all + ${mockito.version} + test + + + + org.powermock + powermock-api-mockito + ${powermock.version} + test + + + + org.powermock + powermock-module-junit4 + ${powermock.version} + test + + + + org.assertj + assertj-core + ${assertj.version} + test + + + info.cukes + cucumber-java8 + ${info.cukes.cucumber.version} + test + + + info.cukes + cucumber-spring + ${info.cukes.cucumber.version} + test + + + info.cukes + cucumber-junit + ${info.cukes.cucumber.version} + test + + + + + + + + + + + + + org.owasp + dependency-check-maven + 1.4.5 + + + + check + + + + + + + + diff --git a/dependency-check-maven/src/it/737-joda-time-issue/postbuild.groovy b/dependency-check-maven/src/it/737-joda-time-issue/postbuild.groovy new file mode 100644 index 000000000..6d52bac4e --- /dev/null +++ b/dependency-check-maven/src/it/737-joda-time-issue/postbuild.groovy @@ -0,0 +1,31 @@ +/* + * This file is part of dependency-check-maven. + * + * 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. + * + * Copyright (c) 2017 Jeremy Long. All Rights Reserved. + */ +/* +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang.StringUtils; +import java.nio.charset.Charset; +import groovy.json.JsonSlurper; + +def slurper = new JsonSlurper() +def json = slurper.parse(new File(basedir, "target/dependency-check-report.json"), "UTF-8") + +assert json instanceof Map +assert json.dependencies instanceof List +assert json.dependencies.size()==0 +return true; +*/ diff --git a/dependency-check-maven/src/it/737-joda-time-issue/prebuild.groovy b/dependency-check-maven/src/it/737-joda-time-issue/prebuild.groovy new file mode 100644 index 000000000..9ec3a0a91 --- /dev/null +++ b/dependency-check-maven/src/it/737-joda-time-issue/prebuild.groovy @@ -0,0 +1,17 @@ +/* + * This file is part of dependency-check-maven. + * + * 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. + * + * Copyright (c) 2017 Jeremy Long. All Rights Reserved. + */ From 9777406460e68d74ed0c36f7f12fab077b1a61fd Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Mon, 29 May 2017 07:21:20 -0400 Subject: [PATCH 15/23] should not have been in this branch --- .../it/737-joda-time-issue/invoker.properties | 19 - .../src/it/737-joda-time-issue/pom.xml | 630 ------------------ .../it/737-joda-time-issue/postbuild.groovy | 31 - .../it/737-joda-time-issue/prebuild.groovy | 17 - 4 files changed, 697 deletions(-) delete mode 100644 dependency-check-maven/src/it/737-joda-time-issue/invoker.properties delete mode 100644 dependency-check-maven/src/it/737-joda-time-issue/pom.xml delete mode 100644 dependency-check-maven/src/it/737-joda-time-issue/postbuild.groovy delete mode 100644 dependency-check-maven/src/it/737-joda-time-issue/prebuild.groovy diff --git a/dependency-check-maven/src/it/737-joda-time-issue/invoker.properties b/dependency-check-maven/src/it/737-joda-time-issue/invoker.properties deleted file mode 100644 index db025b28c..000000000 --- a/dependency-check-maven/src/it/737-joda-time-issue/invoker.properties +++ /dev/null @@ -1,19 +0,0 @@ -# -# This file is part of dependency-check-maven. -# -# 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. -# -# Copyright (c) 2017 Jeremy Long. All Rights Reserved. -# - -invoker.goals = install -X ${project.groupId}:${project.artifactId}:${project.version}:check -DskipSystemScope=true -Dformat=JSON diff --git a/dependency-check-maven/src/it/737-joda-time-issue/pom.xml b/dependency-check-maven/src/it/737-joda-time-issue/pom.xml deleted file mode 100644 index 3b4baa359..000000000 --- a/dependency-check-maven/src/it/737-joda-time-issue/pom.xml +++ /dev/null @@ -1,630 +0,0 @@ - - - - - - - com.test - 4.0.0 - 1.0.9-SNAPSHOT - test pom parent - test-backend-app - test-backend web app - - - 1.8 - 1.8 - 1.8 - UTF-8 - @{project.version} - - **/test/app/resources/*,**/test/app/config/**/*,**/test/model/**/*,**/test/common/**/* - - ${maven.build.timestamp} - dd/MM/yyyy HH:mm:ss - - - -Xdoclint:none - - - 1.1.6 - 1.5.0.RELEASE - 8.0.41 - 3.0.1 - 4.3.6.RELEASE - 1.7.22 - 1.8.10 - 2.8.2 - 1.0.2 - 2.10.3 - - 3.5 - 1.10 - 4.1 - 1.5.1 - 1.3.2 - 2.5 - 1.5.10 - 1.1.3 - 1.16.12 - 1.1.0.Final - 1.0 - 2.23.2 - 5.2.4.Final - - - 4.12 - 1.10.19 - 1.6.6 - 3.6.1 - 1.2.5 - - - 3.0.1 - 3.5.1 - 2.6 - 2.5.3 - 1.10 - 2.10.4 - 3.0.0 - 3.0.2 - 2.7 - 1.0 - 0.7.4.201502262128 - 2.2.4 - 3.0.0 - - - - - - - - - joda-time - joda-time - 1.6 - - - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-jersey - - - org.springframework.boot - spring-boot-starter-tomcat - - - org.springframework.boot - spring-boot-devtools - true - - - org.springframework.boot - spring-boot-actuator - - - org.springframework - spring-context-support - - - org.springframework.boot - spring-boot-loader - - - org.springframework.boot - spring-boot-starter-security - - - - - org.apache.tomcat.embed - tomcat-embed-core - - - org.apache.tomcat.embed - tomcat-embed-el - - - org.apache.tomcat.embed - tomcat-embed-logging-juli - - - org.apache.tomcat.embed - tomcat-embed-websocket - - - - - - org.mapstruct - mapstruct-jdk8 - - - - - - commons-io - commons-io - - - commons-fileupload - commons-fileupload - - - org.apache.commons - commons-lang3 - - - - - - org.glassfish.jersey.media - jersey-media-multipart - - - - - - io.swagger - swagger-jersey2-jaxrs - - - - - - org.slf4j - slf4j-api - - - org.slf4j - jcl-over-slf4j - - - org.slf4j - log4j-over-slf4j - - - org.slf4j - jul-to-slf4j - - - - - - net.sf.ehcache - ehcache - - - - - org.glassfish - javax.json - - - - - junit - junit - - - org.mockito - mockito-all - - - org.springframework - spring-test - - - org.powermock - powermock-api-mockito - - - org.powermock - powermock-module-junit4 - - - org.springframework.boot - spring-boot-starter-test - test - - - - - javax.json - javax.json-api - - - - - - - - - com.slimpay - hapiclient - ${com.slimpay.version} - - - - - org.springframework.boot - spring-boot-starter-jersey - ${spring.boot.version} - - - org.springframework.boot - spring-boot-starter-tomcat - ${spring.boot.version} - - - org.springframework.boot - spring-boot-starter-web - ${spring.boot.version} - - - org.springframework.boot - spring-boot-devtools - ${spring.boot.version} - - - org.springframework.boot - spring-boot-actuator - ${spring.boot.version} - - - org.springframework.boot - spring-boot-loader - ${spring.boot.version} - - - org.springframework.boot - spring-boot-starter-security - ${spring.boot.version} - - - org.springframework.boot - spring-boot-starter-test - ${spring.boot.version} - test - - - - - - org.springframework - spring-core - ${spring.framework.version} - - - - org.springframework - spring-context - ${spring.framework.version} - - - - org.springframework - spring-context-support - ${spring.framework.version} - - - - org.springframework - spring-aop - ${spring.framework.version} - - - - org.springframework - spring-beans - ${spring.framework.version} - - - - org.springframework - spring-web - ${spring.framework.version} - - - - org.springframework - spring-webmvc - ${spring.framework.version} - - - - org.springframework - spring-test - ${spring.framework.version} - - - - - - org.apache.tomcat.embed - tomcat-embed-core - ${tomcat.version} - - - org.apache.tomcat.embed - tomcat-embed-el - ${tomcat.version} - - - org.apache.tomcat.embed - tomcat-embed-logging-juli - ${tomcat.version} - - - org.apache.tomcat.embed - tomcat-embed-jasper - ${tomcat.version} - - - org.apache.tomcat.embed - tomcat-embed-websocket - ${tomcat.version} - - - - - - org.aspectj - aspectjrt - ${aspectj.version} - - - - org.aspectj - aspectjweaver - ${aspectj.version} - - - - - - net.sf.ehcache - ehcache - ${ehcache.version} - - - - - - org.glassfish.jersey.media - jersey-media-multipart - ${jersey.multipart.version} - - - - - org.glassfish - javax.json - 1.0.4 - - - - - - org.apache.commons - commons-lang3 - ${commons-lang.version} - - - - org.apache.commons - commons-collections4 - ${commons-collections.version} - - - - commons-validator - commons-validator - ${commons-validator.version} - - - - commons-codec - commons-codec - ${commons-codec.version} - - - - commons-fileupload - commons-fileupload - ${commons-fileupload.version} - - - - commons-io - commons-io - ${commons-io.version} - - - - javax.servlet - javax.servlet-api - ${servlet-api.version} - provided - - - - com.fasterxml.jackson.core - jackson-core - ${jackson.version} - - - - com.fasterxml.jackson.core - jackson-annotations - ${jackson.version} - - - - com.fasterxml.jackson.core - jackson-databind - ${jackson.version} - - - - com.fasterxml.jackson.jaxrs - jackson-jaxrs-base - ${jackson.version} - - - - com.fasterxml.jackson.jaxrs - jackson-jaxrs-json-provider - ${jackson.version} - - - - io.swagger - swagger-jersey2-jaxrs - ${swagger.version} - - - - org.projectlombok - lombok - ${lombok.version} - provided - - - - org.mapstruct - mapstruct-jdk8 - ${mapstruct.version} - - - - javax.json - javax.json-api - ${javax.json.version} - - - - org.hibernate - hibernate-validator - ${org.hibernate.hibernate-validator.version} - - - - - - - org.slf4j - slf4j-api - ${slf4j.version} - - - - org.slf4j - jcl-over-slf4j - ${slf4j.version} - - - - org.slf4j - log4j-over-slf4j - ${slf4j.version} - - - - org.slf4j - jul-to-slf4j - ${slf4j.version} - - - - ch.qos.logback - logback-classic - ${logback.version} - - - - - - junit - junit - ${junit.version} - test - - - - org.mockito - mockito-all - ${mockito.version} - test - - - - org.powermock - powermock-api-mockito - ${powermock.version} - test - - - - org.powermock - powermock-module-junit4 - ${powermock.version} - test - - - - org.assertj - assertj-core - ${assertj.version} - test - - - info.cukes - cucumber-java8 - ${info.cukes.cucumber.version} - test - - - info.cukes - cucumber-spring - ${info.cukes.cucumber.version} - test - - - info.cukes - cucumber-junit - ${info.cukes.cucumber.version} - test - - - - - - - - - - - - - org.owasp - dependency-check-maven - 1.4.5 - - - - check - - - - - - - - diff --git a/dependency-check-maven/src/it/737-joda-time-issue/postbuild.groovy b/dependency-check-maven/src/it/737-joda-time-issue/postbuild.groovy deleted file mode 100644 index 6d52bac4e..000000000 --- a/dependency-check-maven/src/it/737-joda-time-issue/postbuild.groovy +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of dependency-check-maven. - * - * 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. - * - * Copyright (c) 2017 Jeremy Long. All Rights Reserved. - */ -/* -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang.StringUtils; -import java.nio.charset.Charset; -import groovy.json.JsonSlurper; - -def slurper = new JsonSlurper() -def json = slurper.parse(new File(basedir, "target/dependency-check-report.json"), "UTF-8") - -assert json instanceof Map -assert json.dependencies instanceof List -assert json.dependencies.size()==0 -return true; -*/ diff --git a/dependency-check-maven/src/it/737-joda-time-issue/prebuild.groovy b/dependency-check-maven/src/it/737-joda-time-issue/prebuild.groovy deleted file mode 100644 index 9ec3a0a91..000000000 --- a/dependency-check-maven/src/it/737-joda-time-issue/prebuild.groovy +++ /dev/null @@ -1,17 +0,0 @@ -/* - * This file is part of dependency-check-maven. - * - * 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. - * - * Copyright (c) 2017 Jeremy Long. All Rights Reserved. - */ From ec448438e525b7256808106a8248d759972a6f5b Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Mon, 29 May 2017 08:19:22 -0400 Subject: [PATCH 16/23] fix for issue #710 --- .../owasp/dependencycheck/xml/XmlEntity.java | 309 ++++++++++++++++++ .../dependencycheck/xml/XmlInputStream.java | 269 +++++++++++++++ .../dependencycheck/xml/pom/PomParser.java | 4 +- .../dependencycheck/xml/pom/PomUtilsTest.java | 2 +- .../src/test/resources/jmockit-1.26.pom | 2 +- .../it/710-pom-parse-error/postbuild.groovy | 17 + src/main/config/checkstyle-suppressions.xml | 2 + 7 files changed, 602 insertions(+), 3 deletions(-) create mode 100644 dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/XmlEntity.java create mode 100644 dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/XmlInputStream.java create mode 100644 dependency-check-maven/src/it/710-pom-parse-error/postbuild.groovy diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/XmlEntity.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/XmlEntity.java new file mode 100644 index 000000000..2da3aacdf --- /dev/null +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/XmlEntity.java @@ -0,0 +1,309 @@ +package org.owasp.dependencycheck.xml; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * This is a utility class to convert named XML Entities (such as ø) into + * its HTML encoded Unicode code point (i.e. &#248;). This is a slightly + * modified (class/method rename) from an SO answer: + * https://stackoverflow.com/questions/7286428/help-the-java-sax-parser-to-understand-bad-xml + * + * @author https://stackoverflow.com/users/823393/oldcurmudgeon + */ +public class XmlEntity { + + /** + * Private constructor for a utility class. + */ + private XmlEntity() { + } + + /** + * Converts a named XML entity into its HTML encoded Unicode code point. + * + * @param s the named entity (note, this should not include the leading '&' + * or trailing ';' + * @return the HTML encoded Unicode code point representation of the named + * entity + */ + public static String fromNamedReference(CharSequence s) { + if (s == null) { + return null; + } + final Integer code = SPECIALS.get(s.toString()); + if (code != null) { + return "&#" + code + ";"; + } + return null; + } + + /** + * The map of HTML entities. + */ + private static final Map SPECIALS; + + /** + * Create a map HTML Named Entities to their numeric equivalent. Derived + * from Wikipedia + * http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references + */ + static { + final Map map = new HashMap<>(); + map.put("quot", 34); + map.put("amp", 38); + map.put("apos", 39); + map.put("lt", 60); + map.put("gt", 62); + map.put("nbsp", 160); + map.put("iexcl", 161); + map.put("cent", 162); + map.put("pound", 163); + map.put("curren", 164); + map.put("yen", 165); + map.put("brvbar", 166); + map.put("sect", 167); + map.put("uml", 168); + map.put("copy", 169); + map.put("ordf", 170); + map.put("laquo", 171); + map.put("not", 172); + map.put("shy", 173); + map.put("reg", 174); + map.put("macr", 175); + map.put("deg", 176); + map.put("plusmn", 177); + map.put("sup2", 178); + map.put("sup3", 179); + map.put("acute", 180); + map.put("micro", 181); + map.put("para", 182); + map.put("middot", 183); + map.put("cedil", 184); + map.put("sup1", 185); + map.put("ordm", 186); + map.put("raquo", 187); + map.put("frac14", 188); + map.put("frac12", 189); + map.put("frac34", 190); + map.put("iquest", 191); + map.put("Agrave", 192); + map.put("Aacute", 193); + map.put("Acirc", 194); + map.put("Atilde", 195); + map.put("Auml", 196); + map.put("Aring", 197); + map.put("AElig", 198); + map.put("Ccedil", 199); + map.put("Egrave", 200); + map.put("Eacute", 201); + map.put("Ecirc", 202); + map.put("Euml", 203); + map.put("Igrave", 204); + map.put("Iacute", 205); + map.put("Icirc", 206); + map.put("Iuml", 207); + map.put("ETH", 208); + map.put("Ntilde", 209); + map.put("Ograve", 210); + map.put("Oacute", 211); + map.put("Ocirc", 212); + map.put("Otilde", 213); + map.put("Ouml", 214); + map.put("times", 215); + map.put("Oslash", 216); + map.put("Ugrave", 217); + map.put("Uacute", 218); + map.put("Ucirc", 219); + map.put("Uuml", 220); + map.put("Yacute", 221); + map.put("THORN", 222); + map.put("szlig", 223); + map.put("agrave", 224); + map.put("aacute", 225); + map.put("acirc", 226); + map.put("atilde", 227); + map.put("auml", 228); + map.put("aring", 229); + map.put("aelig", 230); + map.put("ccedil", 231); + map.put("egrave", 232); + map.put("eacute", 233); + map.put("ecirc", 234); + map.put("euml", 235); + map.put("igrave", 236); + map.put("iacute", 237); + map.put("icirc", 238); + map.put("iuml", 239); + map.put("eth", 240); + map.put("ntilde", 241); + map.put("ograve", 242); + map.put("oacute", 243); + map.put("ocirc", 244); + map.put("otilde", 245); + map.put("ouml", 246); + map.put("divide", 247); + map.put("oslash", 248); + map.put("ugrave", 249); + map.put("uacute", 250); + map.put("ucirc", 251); + map.put("uuml", 252); + map.put("yacute", 253); + map.put("thorn", 254); + map.put("yuml", 255); + map.put("OElig", 338); + map.put("oelig", 339); + map.put("Scaron", 352); + map.put("scaron", 353); + map.put("Yuml", 376); + map.put("fnof", 402); + map.put("circ", 710); + map.put("tilde", 732); + map.put("Alpha", 913); + map.put("Beta", 914); + map.put("Gamma", 915); + map.put("Delta", 916); + map.put("Epsilon", 917); + map.put("Zeta", 918); + map.put("Eta", 919); + map.put("Theta", 920); + map.put("Iota", 921); + map.put("Kappa", 922); + map.put("Lambda", 923); + map.put("Mu", 924); + map.put("Nu", 925); + map.put("Xi", 926); + map.put("Omicron", 927); + map.put("Pi", 928); + map.put("Rho", 929); + map.put("Sigma", 931); + map.put("Tau", 932); + map.put("Upsilon", 933); + map.put("Phi", 934); + map.put("Chi", 935); + map.put("Psi", 936); + map.put("Omega", 937); + map.put("alpha", 945); + map.put("beta", 946); + map.put("gamma", 947); + map.put("delta", 948); + map.put("epsilon", 949); + map.put("zeta", 950); + map.put("eta", 951); + map.put("theta", 952); + map.put("iota", 953); + map.put("kappa", 954); + map.put("lambda", 955); + map.put("mu", 956); + map.put("nu", 957); + map.put("xi", 958); + map.put("omicron", 959); + map.put("pi", 960); + map.put("rho", 961); + map.put("sigmaf", 962); + map.put("sigma", 963); + map.put("tau", 964); + map.put("upsilon", 965); + map.put("phi", 966); + map.put("chi", 967); + map.put("psi", 968); + map.put("omega", 969); + map.put("thetasym", 977); + map.put("upsih", 978); + map.put("piv", 982); + map.put("ensp", 8194); + map.put("emsp", 8195); + map.put("thinsp", 8201); + map.put("zwnj", 8204); + map.put("zwj", 8205); + map.put("lrm", 8206); + map.put("rlm", 8207); + map.put("ndash", 8211); + map.put("mdash", 8212); + map.put("lsquo", 8216); + map.put("rsquo", 8217); + map.put("sbquo", 8218); + map.put("ldquo", 8220); + map.put("rdquo", 8221); + map.put("bdquo", 8222); + map.put("dagger", 8224); + map.put("Dagger", 8225); + map.put("bull", 8226); + map.put("hellip", 8230); + map.put("permil", 8240); + map.put("prime", 8242); + map.put("Prime", 8243); + map.put("lsaquo", 8249); + map.put("rsaquo", 8250); + map.put("oline", 8254); + map.put("frasl", 8260); + map.put("euro", 8364); + map.put("image", 8465); + map.put("weierp", 8472); + map.put("real", 8476); + map.put("trade", 8482); + map.put("alefsym", 8501); + map.put("larr", 8592); + map.put("uarr", 8593); + map.put("rarr", 8594); + map.put("darr", 8595); + map.put("harr", 8596); + map.put("crarr", 8629); + map.put("lArr", 8656); + map.put("uArr", 8657); + map.put("rArr", 8658); + map.put("dArr", 8659); + map.put("hArr", 8660); + map.put("forall", 8704); + map.put("part", 8706); + map.put("exist", 8707); + map.put("empty", 8709); + map.put("nabla", 8711); + map.put("isin", 8712); + map.put("notin", 8713); + map.put("ni", 8715); + map.put("prod", 8719); + map.put("sum", 8721); + map.put("minus", 8722); + map.put("lowast", 8727); + map.put("radic", 8730); + map.put("prop", 8733); + map.put("infin", 8734); + map.put("ang", 8736); + map.put("and", 8743); + map.put("or", 8744); + map.put("cap", 8745); + map.put("cup", 8746); + map.put("int", 8747); + map.put("there4", 8756); + map.put("sim", 8764); + map.put("cong", 8773); + map.put("asymp", 8776); + map.put("ne", 8800); + map.put("equiv", 8801); + map.put("le", 8804); + map.put("ge", 8805); + map.put("sub", 8834); + map.put("sup", 8835); + map.put("nsub", 8836); + map.put("sube", 8838); + map.put("supe", 8839); + map.put("oplus", 8853); + map.put("otimes", 8855); + map.put("perp", 8869); + map.put("sdot", 8901); + map.put("lceil", 8968); + map.put("rceil", 8969); + map.put("lfloor", 8970); + map.put("rfloor", 8971); + map.put("lang", 10216); + map.put("rang", 10217); + map.put("loz", 9674); + map.put("spades", 9824); + map.put("clubs", 9827); + map.put("hearts", 9829); + map.put("diams", 9830); + SPECIALS = Collections.unmodifiableMap(map); + } +} diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/XmlInputStream.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/XmlInputStream.java new file mode 100644 index 000000000..2879c2baf --- /dev/null +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/XmlInputStream.java @@ -0,0 +1,269 @@ +package org.owasp.dependencycheck.xml; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Cleans up often very bad XML. Primarily, this will convert named HTM entities + * into their HTM encoded Unicode code point representation. + * + *
        + *
      1. Strips leading white space
      2. + *
      3. Recodes &pound; etc to &#...;
      4. + *
      5. Recodes lone & as &amp;
      6. + *
      + *

      + * This is a slightly modified (class/method rename) from an SO answer: + * https://stackoverflow.com/questions/7286428/help-the-java-sax-parser-to-understand-bad-xml

      + * + * @author https://stackoverflow.com/users/823393/oldcurmudgeon + */ +public class XmlInputStream extends FilterInputStream { + + /** + * The logger. + */ + private static final Logger LOGGER = LoggerFactory.getLogger(XmlInputStream.class); + /** + * The minimum length of characters to read. + */ + private static final int MIN_LENGTH = 2; + /** + * Holder for everything we've read. + */ + private StringBuilder red = new StringBuilder(); + /** + * Data that needs to be pushed back. + */ + private StringBuilder pushBack = new StringBuilder(); + /** + * How much we've given them. + */ + private int given = 0; + /** + * How much we've read. + */ + private int pulled = 0; + + /** + * Constructs a new XML Input Stream. + * + * @param in the base input stream + */ + public XmlInputStream(InputStream in) { + super(in); + } + + /** + * NB: This is a Troll length (i.e. it goes 1, 2, many) so 2 actually means + * "at least 2" + * + * @return the length + */ + public int length() { + try { + final StringBuilder s = read(MIN_LENGTH); + pushBack.append(s); + return s.length(); + } catch (IOException ex) { + LOGGER.warn("Oops ", ex); + } + return 0; + } + + /** + * Read n characters. + * + * @param n the number of characters to read + * @return the characters read + * @throws IOException thrown when an error occurs + */ + private StringBuilder read(int n) throws IOException { + // Input stream finished? + boolean eof = false; + // Read that many. + final StringBuilder s = new StringBuilder(n); + while (s.length() < n && !eof) { + // Always get from the pushBack buffer. + if (pushBack.length() == 0) { + // Read something from the stream into pushBack. + eof = readIntoPushBack(); + } + + // Pushback only contains deliverable codes. + if (pushBack.length() > 0) { + // Grab one character + s.append(pushBack.charAt(0)); + // Remove it from pushBack + pushBack.deleteCharAt(0); + } + + } + return s; + } + + /** + * Might not actually push back anything but usually will. + * + * @return true if at end-of-file + * @throws IOException thrown if there is an IO exception in the underlying + * steam + */ + private boolean readIntoPushBack() throws IOException { + // File finished? + boolean eof = false; + // Next char. + final int ch = in.read(); + if (ch >= 0) { + // Discard whitespace at start? + if (!(pulled == 0 && isWhiteSpace(ch))) { + // Good code. + pulled += 1; + // Parse out the &stuff; + if (ch == '&') { + // Process the & + readAmpersand(); + } else { + // Not an '&', just append. + pushBack.append((char) ch); + } + } + } else { + // Hit end of file. + eof = true; + } + return eof; + } + + /** + * Deal with an ampersand in the stream. + * + * @throws IOException thrown if an unknown entity is encountered + */ + private void readAmpersand() throws IOException { + // Read the whole word, up to and including the ; + final StringBuilder reference = new StringBuilder(); + int ch; + // Should end in a ';' + for (ch = in.read(); isAlphaNumeric(ch); ch = in.read()) { + reference.append((char) ch); + } + // Did we tidily finish? + if (ch == ';') { + // Yes! Translate it into a &#nnn; code. + final String code = XmlEntity.fromNamedReference(reference); + if (code != null) { + // Keep it. + pushBack.append(code); + } else { + throw new IOException("Invalid/Unknown reference '&" + reference + ";'"); + } + } else { + // Did not terminate properly! + // Perhaps an & on its own or a malformed reference. + // Either way, escape the & + pushBack.append("&").append(reference).append((char) ch); + } + } + + /** + * Keep track of what we've given them. + * + * @param s the sequence of characters given + * @param wanted the number of characters wanted + * @param got the number of characters given + */ + private void given(CharSequence s, int wanted, int got) { + red.append(s); + given += got; + LOGGER.trace("Given: [" + wanted + "," + got + "]-" + s); + } + + /** + * Reads the next byte. + * + * @return the byte read + * @throws IOException thrown when there is an problem reading + */ + @Override + public int read() throws IOException { + final StringBuilder s = read(1); + given(s, 1, 1); + return s.length() > 0 ? s.charAt(0) : -1; + } + + /** + * Reads the next length of bytes from the stream into the given byte array + * at the given offset. + * + * @param data the buffer to store the data read + * @param offset the offset in the buffer to start writing + * @param length the length of data to read + * @return the number of bytes read + * @throws IOException thrown when there is an issue with the underlying + * stream + */ + @Override + public int read(byte[] data, int offset, int length) throws IOException { + final StringBuilder s = read(length); + int n = 0; + for (int i = 0; i < Math.min(length, s.length()); i++) { + data[offset + i] = (byte) s.charAt(i); + n += 1; + } + given(s, length, n); + return n > 0 ? n : -1; + } + + /** + * To string implementation. + * + * @return a string representation of the data given and read from the + * stream. + */ + @Override + public String toString() { + final String s = red.toString(); + final StringBuilder h = new StringBuilder(); + // Hex dump the small ones. + if (s.length() < 8) { + for (int i = 0; i < s.length(); i++) { + h.append(" ").append(Integer.toHexString(s.charAt(i))); + } + } + return "[" + given + "]-\"" + s + "\"" + (h.length() > 0 ? " (" + h.toString() + ")" : ""); + } + + /** + * Determines if the character is whitespace. + * + * @param ch the character to check + * @return true if the character is whitespace; otherwise false + */ + private boolean isWhiteSpace(int ch) { + switch (ch) { + case ' ': + case '\r': + case '\n': + case '\t': + return true; + default: + return false; + } + } + + /** + * Checks if the given character is alpha-numeric. + * + * @param ch the character to check + * @return true if the character is alpha-numeric; otherwise false. + */ + private boolean isAlphaNumeric(int ch) { + return ('a' <= ch && ch <= 'z') + || ('A' <= ch && ch <= 'Z') + || ('0' <= ch && ch <= '9'); + } +} diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/pom/PomParser.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/pom/PomParser.java index 8de5bcb2e..155b0048a 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/pom/PomParser.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/pom/PomParser.java @@ -29,6 +29,7 @@ import javax.xml.parsers.SAXParser; import org.apache.commons.io.ByteOrderMark; import org.apache.commons.io.input.BOMInputStream; import org.owasp.dependencycheck.utils.XmlUtils; +import org.owasp.dependencycheck.xml.XmlInputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -80,7 +81,8 @@ public class PomParser { final SAXParser saxParser = XmlUtils.buildSecureSaxParser(); final XMLReader xmlReader = saxParser.getXMLReader(); xmlReader.setContentHandler(handler); - final BOMInputStream bomStream = new BOMInputStream(inputStream); + + final BOMInputStream bomStream = new BOMInputStream(new XmlInputStream(inputStream)); final ByteOrderMark bom = bomStream.getBOM(); final String defaultEncoding = "UTF-8"; final String charsetName = bom == null ? defaultEncoding : bom.getCharsetName(); diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/pom/PomUtilsTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/pom/PomUtilsTest.java index 3b5c285bf..879e1217f 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/pom/PomUtilsTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/pom/PomUtilsTest.java @@ -49,7 +49,7 @@ public class PomUtilsTest extends BaseTest { assertEquals(expResult, result.getOrganizationUrl()); file = BaseTest.getResourceAsFile(this, "jmockit-1.26.pom"); - expResult = "Main"; + expResult = "Main ΓΈ modified to test issue #710"; result = PomUtils.readPom(file); assertEquals(expResult, result.getName()); } diff --git a/dependency-check-core/src/test/resources/jmockit-1.26.pom b/dependency-check-core/src/test/resources/jmockit-1.26.pom index 590d69b63..3faac78be 100644 --- a/dependency-check-core/src/test/resources/jmockit-1.26.pom +++ b/dependency-check-core/src/test/resources/jmockit-1.26.pom @@ -7,7 +7,7 @@ org.jmockitjmockit1.26 jar - Main + Main ø modified to test issue #710 JMockit is a Java toolkit for automated developer testing. It contains mocking and faking APIs and a code coverage tool, supporting both JUnit and TestNG. diff --git a/dependency-check-maven/src/it/710-pom-parse-error/postbuild.groovy b/dependency-check-maven/src/it/710-pom-parse-error/postbuild.groovy new file mode 100644 index 000000000..9ec3a0a91 --- /dev/null +++ b/dependency-check-maven/src/it/710-pom-parse-error/postbuild.groovy @@ -0,0 +1,17 @@ +/* + * This file is part of dependency-check-maven. + * + * 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. + * + * Copyright (c) 2017 Jeremy Long. All Rights Reserved. + */ diff --git a/src/main/config/checkstyle-suppressions.xml b/src/main/config/checkstyle-suppressions.xml index 56ec1750f..46acbbaf7 100644 --- a/src/main/config/checkstyle-suppressions.xml +++ b/src/main/config/checkstyle-suppressions.xml @@ -12,4 +12,6 @@ + + \ No newline at end of file From a076ce6e8ea46e417b18afe1ecb192213bb063ce Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Mon, 29 May 2017 08:20:11 -0400 Subject: [PATCH 17/23] fix coverage results to codacy --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 75e4c7e78..b0e0eeca1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ env: before_install: - sudo apt-get install jq - - wget -O ~/codacy-coverage-reporter-assembly-latest.jar $(curl https://api.github.com/repos/codacy/codacy-coverage-reporter/releases/latest | jq -r .assets[0].browser_download_url) + - wget -O ~/codacy-coverage-reporter-assembly.jar $(curl https://oss.sonatype.org/service/local/repositories/releases/content/com/codacy/codacy-coverage-reporter/1.0.13/codacy-coverage-reporter-1.0.13-assembly.jar | jq -r .assets[0].browser_download_url) after_success: - - java -cp ~/codacy-coverage-reporter-assembly-latest.jar com.codacy.CodacyCoverageReporter -l Java -r build-reporting/target/site/jacoco-aggregate/jacoco.xml + - java -cp ~/codacy-coverage-reporter-assembly.jar com.codacy.CodacyCoverageReporter -l Java -r build-reporting/target/site/jacoco-aggregate/jacoco.xml From 72aec26ede2563b6111a4317b6b109b2d9ada92d Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Mon, 29 May 2017 08:21:40 -0400 Subject: [PATCH 18/23] test cases for fix of issue #710 --- .../dependencycheck/xml/XmlEntityTest.java | 59 ++++++++ .../xml/XmlInputStreamTest.java | 138 ++++++++++++++++++ .../it/710-pom-parse-error/invoker.properties | 19 +++ .../src/it/710-pom-parse-error/pom.xml | 32 ++++ .../it/710-pom-parse-error/prebuild.groovy | 17 +++ 5 files changed, 265 insertions(+) create mode 100644 dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/XmlEntityTest.java create mode 100644 dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/XmlInputStreamTest.java create mode 100644 dependency-check-maven/src/it/710-pom-parse-error/invoker.properties create mode 100644 dependency-check-maven/src/it/710-pom-parse-error/pom.xml create mode 100644 dependency-check-maven/src/it/710-pom-parse-error/prebuild.groovy diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/XmlEntityTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/XmlEntityTest.java new file mode 100644 index 000000000..53f2cc3d8 --- /dev/null +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/XmlEntityTest.java @@ -0,0 +1,59 @@ +/* + * This file is part of dependency-check-core. + * + * 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. + * + * Copyright (c) 2017 Jeremy Long. All Rights Reserved. + */ +package org.owasp.dependencycheck.xml; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author Jeremy Long + */ +public class XmlEntityTest { + + /** + * Test of fromNamedReference method, of class XmlEntity. + */ + @Test + public void testFromNamedReference() { + CharSequence s = null; + String expResult = null; + String result = XmlEntity.fromNamedReference(s); + assertEquals(expResult, result); + + s = "somethingWrong"; + expResult = null; + result = XmlEntity.fromNamedReference(s); + assertEquals(expResult, result); + + s = "amp"; + expResult = "&"; + result = XmlEntity.fromNamedReference(s); + assertEquals(expResult, result); + + s = "acute"; + expResult = "´"; + result = XmlEntity.fromNamedReference(s); + assertEquals(expResult, result); + } + +} diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/XmlInputStreamTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/XmlInputStreamTest.java new file mode 100644 index 000000000..cd2e44504 --- /dev/null +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/XmlInputStreamTest.java @@ -0,0 +1,138 @@ +/* + * This file is part of dependency-check-core. + * + * 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. + * + * Copyright (c) 2017 Jeremy Long. All Rights Reserved. + */ +package org.owasp.dependencycheck.xml; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author jerem + */ +public class XmlInputStreamTest { + + /** + * Test of length method, of class XmlInputStream. + */ + @Test + public void testLength() { + String data = ""; + InputStream stream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)); + XmlInputStream instance = new XmlInputStream(stream); + int expResult = 0; + int result = instance.length(); + assertEquals(expResult, result); + + data = "Input data"; + stream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)); + instance = new XmlInputStream(stream); + result = instance.length(); + assertTrue(result > 0); + } + + /** + * Test of read method, of class XmlInputStream. + */ + @Test + public void testRead_0args() throws Exception { + String data = ""; + InputStream stream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)); + XmlInputStream instance = new XmlInputStream(stream); + int expResult = -1; + int result = instance.read(); + assertEquals(expResult, result); + + data = "*"; + stream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)); + instance = new XmlInputStream(stream); + expResult = 42; + result = instance.read(); + assertEquals(expResult, result); + } + + /** + * Test of read method, of class XmlInputStream. + */ + @Test + public void testRead_3args() throws Exception { + byte[] data = new byte[10]; + int offset = 0; + int length = 10; + byte[] expected = "abcdefghij".getBytes(StandardCharsets.UTF_8); + String text = "abcdefghijklmnopqrstuvwxyz"; + InputStream stream = new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8)); + XmlInputStream instance = new XmlInputStream(stream); + int expResult = 10; + int result = instance.read(data, offset, length); + assertEquals(expResult, result); + assertArrayEquals(expected, data); + + + data = new byte[5]; + offset = 0; + length = 5; + expected = "&".getBytes(StandardCharsets.UTF_8); + text = "&"; + stream = new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8)); + instance = new XmlInputStream(stream); + expResult = 5; + result = instance.read(data, offset, length); + assertEquals(expResult, result); + assertArrayEquals(expected, data); + + data = new byte[10]; + offset = 0; + length = 10; + expected = "& test".getBytes(StandardCharsets.UTF_8); + text = "& test"; + stream = new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8)); + instance = new XmlInputStream(stream); + expResult = 10; + result = instance.read(data, offset, length); + assertEquals(expResult, result); + assertArrayEquals(expected, data); + } + + /** + * Test of toString method, of class XmlInputStream. + */ + @Test + public void testToString() throws IOException { + String data = "test"; + InputStream stream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)); + XmlInputStream instance = new XmlInputStream(stream); + int r = instance.read(); + String expResult = "[1]-\"t\" ( 74)"; + String result = instance.toString(); + assertEquals(expResult, result); + r = instance.read(); + expResult = "[2]-\"te\" ( 74 65)"; + result = instance.toString(); + assertEquals(expResult, result); + + } +} diff --git a/dependency-check-maven/src/it/710-pom-parse-error/invoker.properties b/dependency-check-maven/src/it/710-pom-parse-error/invoker.properties new file mode 100644 index 000000000..693fb2637 --- /dev/null +++ b/dependency-check-maven/src/it/710-pom-parse-error/invoker.properties @@ -0,0 +1,19 @@ +# +# This file is part of dependency-check-maven. +# +# 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. +# +# Copyright (c) 2014 Jeremy Long. All Rights Reserved. +# + +invoker.goals = install ${project.groupId}:${project.artifactId}:${project.version}:check -X -Dformat=ALL diff --git a/dependency-check-maven/src/it/710-pom-parse-error/pom.xml b/dependency-check-maven/src/it/710-pom-parse-error/pom.xml new file mode 100644 index 000000000..0adbf19b9 --- /dev/null +++ b/dependency-check-maven/src/it/710-pom-parse-error/pom.xml @@ -0,0 +1,32 @@ + + + + 4.0.0 + org.owasp.test + pom-parse-error + 1.0.0-SNAPSHOT + jar + + + qdox + qdox + 1.6.1 + + + \ No newline at end of file diff --git a/dependency-check-maven/src/it/710-pom-parse-error/prebuild.groovy b/dependency-check-maven/src/it/710-pom-parse-error/prebuild.groovy new file mode 100644 index 000000000..9eff4bb5c --- /dev/null +++ b/dependency-check-maven/src/it/710-pom-parse-error/prebuild.groovy @@ -0,0 +1,17 @@ +/* + * This file is part of dependency-check-maven. + * + * 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. + * + * Copyright (c) 2014 Jeremy Long. All Rights Reserved. + */ From 217b08b5712992b6ad3c6d6e76eed4806ea8a560 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Mon, 29 May 2017 12:04:06 -0400 Subject: [PATCH 19/23] fix wget --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b0e0eeca1..0c63a525f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ env: before_install: - sudo apt-get install jq - - wget -O ~/codacy-coverage-reporter-assembly.jar $(curl https://oss.sonatype.org/service/local/repositories/releases/content/com/codacy/codacy-coverage-reporter/1.0.13/codacy-coverage-reporter-1.0.13-assembly.jar | jq -r .assets[0].browser_download_url) + - wget -O ~/codacy-coverage-reporter-assembly.jar https://oss.sonatype.org/service/local/repositories/releases/content/com/codacy/codacy-coverage-reporter/1.0.13/codacy-coverage-reporter-1.0.13-assembly.jar after_success: - java -cp ~/codacy-coverage-reporter-assembly.jar com.codacy.CodacyCoverageReporter -l Java -r build-reporting/target/site/jacoco-aggregate/jacoco.xml From d355cab2f98849e4141929c50c5d740950a91eed Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Tue, 30 May 2017 06:44:00 -0400 Subject: [PATCH 20/23] minor codacy requested fixes --- .../owasp/dependencycheck/xml/XmlEntity.java | 53 ++++++++++--------- .../dependencycheck/xml/XmlEntityTest.java | 4 -- .../xml/XmlInputStreamTest.java | 7 +-- 3 files changed, 29 insertions(+), 35 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/XmlEntity.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/XmlEntity.java index 2da3aacdf..acad80fa7 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/XmlEntity.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/XmlEntity.java @@ -13,37 +13,12 @@ import java.util.Map; * @author https://stackoverflow.com/users/823393/oldcurmudgeon */ public class XmlEntity { - - /** - * Private constructor for a utility class. - */ - private XmlEntity() { - } - - /** - * Converts a named XML entity into its HTML encoded Unicode code point. - * - * @param s the named entity (note, this should not include the leading '&' - * or trailing ';' - * @return the HTML encoded Unicode code point representation of the named - * entity - */ - public static String fromNamedReference(CharSequence s) { - if (s == null) { - return null; - } - final Integer code = SPECIALS.get(s.toString()); - if (code != null) { - return "&#" + code + ";"; - } - return null; - } - /** * The map of HTML entities. */ private static final Map SPECIALS; + // /** * Create a map HTML Named Entities to their numeric equivalent. Derived * from Wikipedia @@ -306,4 +281,30 @@ public class XmlEntity { map.put("diams", 9830); SPECIALS = Collections.unmodifiableMap(map); } + // + + /** + * Private constructor for a utility class. + */ + private XmlEntity() { + } + + /** + * Converts a named XML entity into its HTML encoded Unicode code point. + * + * @param s the named entity (note, this should not include the leading '&' + * or trailing ';' + * @return the HTML encoded Unicode code point representation of the named + * entity + */ + public static String fromNamedReference(CharSequence s) { + if (s == null) { + return null; + } + final Integer code = SPECIALS.get(s.toString()); + if (code != null) { + return "&#" + code + ";"; + } + return null; + } } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/XmlEntityTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/XmlEntityTest.java index 53f2cc3d8..6d143ddd8 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/XmlEntityTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/XmlEntityTest.java @@ -17,10 +17,6 @@ */ package org.owasp.dependencycheck.xml; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/XmlInputStreamTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/XmlInputStreamTest.java index cd2e44504..f2382f7ab 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/XmlInputStreamTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/XmlInputStreamTest.java @@ -21,11 +21,6 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; @@ -126,10 +121,12 @@ public class XmlInputStreamTest { InputStream stream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)); XmlInputStream instance = new XmlInputStream(stream); int r = instance.read(); + assertEquals('t', r); String expResult = "[1]-\"t\" ( 74)"; String result = instance.toString(); assertEquals(expResult, result); r = instance.read(); + assertEquals('e', r); expResult = "[2]-\"te\" ( 74 65)"; result = instance.toString(); assertEquals(expResult, result); From ee1934f74b8c5cda30f0d9c98805088edd7c18f8 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Tue, 30 May 2017 20:14:57 -0400 Subject: [PATCH 21/23] fix travis build to post jacoco coverage to codacy --- .travis.yml | 2 +- build-reporting/pom.xml | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0c63a525f..cc3c56072 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,4 +10,4 @@ before_install: - wget -O ~/codacy-coverage-reporter-assembly.jar https://oss.sonatype.org/service/local/repositories/releases/content/com/codacy/codacy-coverage-reporter/1.0.13/codacy-coverage-reporter-1.0.13-assembly.jar after_success: - - java -cp ~/codacy-coverage-reporter-assembly.jar com.codacy.CodacyCoverageReporter -l Java -r build-reporting/target/site/jacoco-aggregate/jacoco.xml + - java -cp ~/codacy-coverage-reporter-assembly.jar com.codacy.CodacyCoverageReporter -l Java -r build-reporting/target/coverage-reports/jacoco.xml diff --git a/build-reporting/pom.xml b/build-reporting/pom.xml index ae73355ef..011fbb12a 100644 --- a/build-reporting/pom.xml +++ b/build-reporting/pom.xml @@ -22,7 +22,7 @@ Copyright (c) 2017 - Jeremy Long. All Rights Reserved. dependency-check-parent 2.0.0-SNAPSHOT - + Dependency-Check Build-Reporting build-reporting pom @@ -80,6 +80,13 @@ Copyright (c) 2017 - Jeremy Long. All Rights Reserved. report-aggregate + + target/coverage-reports/ + + target/coverage-reports/jacoco-ut.exec + target/coverage-reports/jacoco-it.exec + +
      From a8add1425510af7b31450f78c1a823b6bb1749c9 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Fri, 2 Jun 2017 05:47:21 -0400 Subject: [PATCH 22/23] incremented missed java6 reference --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ed1919d21..c76264c30 100644 --- a/pom.xml +++ b/pom.xml @@ -478,7 +478,7 @@ Copyright (c) 2012 - Jeremy Long org.codehaus.mojo.signature - java16 + java17 1.1 From 839d869137363a4a061d4158471a79eeaee25b38 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Fri, 2 Jun 2017 06:20:01 -0400 Subject: [PATCH 23/23] attempting to get coverity to scan via the matrix only when a cron job occurs --- .travis.yml | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index cc3c56072..ed2f38e1a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,11 +3,22 @@ jdk: oraclejdk7 script: mvn install -DreleaseTesting env: global: - secure: ZUzhWfpXJw/oAeDlUkDFkEJMT0T7kCN3d7ah8urkL2B0KFfKOqQagkbXkgvDa1SYud8VdcnoGa69LfkEr5IrdqW7R4bEYZAiN5swm4Z0iO8t53szVspm2f+O9jQ44O/sfOfpfLxWUUuhdc7Vbrszp+tSszxdPmssWL+f5a/mfWs= - + - secure: ZUzhWfpXJw/oAeDlUkDFkEJMT0T7kCN3d7ah8urkL2B0KFfKOqQagkbXkgvDa1SYud8VdcnoGa69LfkEr5IrdqW7R4bEYZAiN5swm4Z0iO8t53szVspm2f+O9jQ44O/sfOfpfLxWUUuhdc7Vbrszp+tSszxdPmssWL+f5a/mfWs= + - secure: pmFymoI7qH0Kna3NkcHrqLiTVWKmrhwqA4Z9U6XLhWDQxcs5g94wCCKpGB6Lkz9mkvRxBRFpZZelnXJa9W9mnuVOMIa5tQfS5gBuaNXOe7AXXdc+Y2975OR9sSfvf16FxLFvNJILmZq+bpMLs+EXaQvjYQHW2O6OWZdLhAPVG6A= before_install: - - sudo apt-get install jq - - wget -O ~/codacy-coverage-reporter-assembly.jar https://oss.sonatype.org/service/local/repositories/releases/content/com/codacy/codacy-coverage-reporter/1.0.13/codacy-coverage-reporter-1.0.13-assembly.jar - +- wget -O ~/codacy-coverage-reporter-assembly.jar https://oss.sonatype.org/service/local/repositories/releases/content/com/codacy/codacy-coverage-reporter/1.0.13/codacy-coverage-reporter-1.0.13-assembly.jar after_success: - - java -cp ~/codacy-coverage-reporter-assembly.jar com.codacy.CodacyCoverageReporter -l Java -r build-reporting/target/coverage-reports/jacoco.xml +- java -cp ~/codacy-coverage-reporter-assembly.jar com.codacy.CodacyCoverageReporter + -l Java -r build-reporting/target/coverage-reports/jacoco.xml +matrix: + include: + - env: CRON_ONLY=1 + addons: + coverity_scan: + project: + name: OWASP dependency-check + version: 1.0 + description: A software composition analsis tools that detects publicly + disclosed vulnerabilities in application dependencies. + build_command: mvn -DskipTests=true package + branch_pattern: master