From e2a1a595431161034d97e8ae2aab0c4679f0b7e9 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Fri, 31 Mar 2017 06:58:37 -0400 Subject: [PATCH] fixed issues related to making the cveDb a singleton --- .../owasp/dependencycheck/taskdefs/Check.java | 5 +- .../taskdefs/DependencyCheckTaskTest.java | 6 -- .../java/org/owasp/dependencycheck/App.java | 11 ++- .../org/owasp/dependencycheck/Engine.java | 80 +++++++++++++------ .../agent/DependencyCheckScanAgent.java | 8 +- .../dependencycheck/analyzer/CPEAnalyzer.java | 2 +- .../analyzer/NvdCveAnalyzer.java | 2 +- .../analyzer/RubyBundleAuditAnalyzer.java | 13 +-- .../data/nvdcve/ConnectionFactory.java | 20 ++++- .../dependencycheck/data/nvdcve/CveDB.java | 7 +- .../data/update/EngineVersionCheck.java | 5 +- .../data/update/NvdCveUpdater.java | 27 +++---- .../owasp/dependencycheck/BaseDBTestCase.java | 1 - .../EngineIntegrationTest.java | 9 ++- .../analyzer/RubyBundleAuditAnalyzerTest.java | 26 +++--- .../data/nvdcve/CveDBIntegrationTest.java | 12 +-- .../data/nvdcve/CveDBMySQLTest.java | 13 +-- .../DatabasePropertiesIntegrationTest.java | 10 +-- .../ReportGeneratorIntegrationTest.java | 2 +- .../maven/BaseDependencyCheckMojo.java | 4 +- 20 files changed, 153 insertions(+), 110 deletions(-) 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 426f90cc0..5cc1e8226 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 @@ -941,14 +941,11 @@ public class Check extends Update { } } DatabaseProperties prop = null; - try { - final CveDB cve = CveDB.getInstance(); + 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); - } finally { - CveDB.close(); } final ReportGenerator reporter = new ReportGenerator(getProjectName(), engine.getDependencies(), engine.getAnalyzers(), prop); diff --git a/dependency-check-ant/src/test/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTaskTest.java b/dependency-check-ant/src/test/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTaskTest.java index 5cb27bdc3..04a6b4c44 100644 --- a/dependency-check-ant/src/test/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTaskTest.java +++ b/dependency-check-ant/src/test/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTaskTest.java @@ -33,7 +33,6 @@ import static org.junit.Assert.assertTrue; import org.owasp.dependencycheck.data.nvdcve.CveDB; import org.owasp.dependencycheck.data.nvdcve.DatabaseException; - /** * * @author Jeremy Long @@ -50,7 +49,6 @@ public class DependencyCheckTaskTest { public void setUp() throws Exception { Settings.initialize(); BaseDBTestCase.ensureDBExists(); - CveDB.getInstance().openDatabase(); final String buildFile = this.getClass().getClassLoader().getResource("build.xml").getPath(); buildFileRule.configureProject(buildFile); } @@ -60,10 +58,6 @@ public class DependencyCheckTaskTest { //no cleanup... //executeTarget("cleanup"); Settings.cleanup(true); - try { - CveDB.getInstance().closeDatabase(); - } catch (DatabaseException ex) { - } } /** 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 b8a0abe19..52c6fce77 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 @@ -282,10 +282,15 @@ public class App { exCol = ex; } final List dependencies = engine.getDependencies(); - final CveDB cve = CveDB.getInstance(); - final DatabaseProperties prop = cve.getDatabaseProperties(); + 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); - CveDB.close(); + try { report.generateReports(reportDirectory, outputFormat); } catch (ReportException ex) { 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 8be22c518..bfbc066c8 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 @@ -38,6 +38,7 @@ import org.slf4j.LoggerFactory; import java.io.File; import java.io.FileFilter; +import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -83,6 +84,10 @@ public class Engine implements FileFilter { * services. */ private ClassLoader serviceClassLoader = Thread.currentThread().getContextClassLoader(); + /** + * A reference to the database. + */ + private CveDB database = null; /** * The Logger for use throughout the class. */ @@ -126,7 +131,10 @@ public class Engine implements FileFilter { * Properly cleans up resources allocated during analysis. */ public void cleanup() { - CveDB.close(); + if (database != null) { + database.close(); + database = null; + } ConnectionFactory.cleanup(); } @@ -479,31 +487,14 @@ public class Engine implements FileFilter { */ public void analyzeDependencies() throws ExceptionCollection { final List exceptions = Collections.synchronizedList(new ArrayList()); - boolean autoUpdate = true; - try { - autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); - } catch (InvalidSettingException ex) { - LOGGER.debug("Invalid setting for auto-update; using true."); - exceptions.add(ex); - } - if (autoUpdate) { - try { - doUpdates(); - } catch (UpdateException ex) { - exceptions.add(ex); - LOGGER.warn("Unable to update Cached Web DataSource, using local " - + "data instead. Results may not include recent vulnerabilities."); - LOGGER.debug("Update Error", ex); - } - } + + initializeAndUpdateDatabase(exceptions); //need to ensure that data exists try { ensureDataExists(); } catch (NoDataException ex) { throwFatalExceptionCollection("Unable to continue dependency-check analysis.", ex, exceptions); - } catch (DatabaseException ex) { - throwFatalExceptionCollection("Unable to connect to the dependency-check database.", ex, exceptions); } LOGGER.debug("\n----------------------------------------------------\nBEGIN ANALYSIS\n----------------------------------------------------"); @@ -550,6 +541,47 @@ public class Engine implements FileFilter { } } + /** + * Performs any necessary updates and initializes the database. + * + * @param exceptions a collection to store non-fatal exceptions + * @throws ExceptionCollection thrown if fatal exceptions occur + */ + private void initializeAndUpdateDatabase(final List exceptions) throws ExceptionCollection { + boolean autoUpdate = true; + try { + autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); + } catch (InvalidSettingException ex) { + LOGGER.debug("Invalid setting for auto-update; using true."); + exceptions.add(ex); + } + if (autoUpdate) { + try { + database = CveDB.getInstance(); + doUpdates(); + } catch (UpdateException ex) { + exceptions.add(ex); + LOGGER.warn("Unable to update Cached Web DataSource, using local " + + "data instead. Results may not include recent vulnerabilities."); + LOGGER.debug("Update Error", ex); + } catch (DatabaseException ex) { + throw new ExceptionCollection("Unable to connect to the database", ex); + } + } else { + try { + if (ConnectionFactory.isH2Connection() && !ConnectionFactory.h2DataFileExists()) { + throw new ExceptionCollection(new NoDataException("Autoupdate is disabled and the database does not exist"), true); + } else { + database = CveDB.getInstance(); + } + } catch (IOException ex) { + throw new ExceptionCollection(new DatabaseException("Autoupdate is disabled and unable to connect to the database"), true); + } catch (DatabaseException ex) { + throwFatalExceptionCollection("Unable to connect to the dependency-check database.", ex, exceptions); + } + } + } + /** * Executes executes the analyzer using multiple threads. * @@ -742,15 +774,11 @@ public class Engine implements FileFilter { * NoDataException is thrown. * * @throws NoDataException thrown if no data exists in the CPE Index - * @throws DatabaseException thrown if there is an exception opening the - * database */ - private void ensureDataExists() throws NoDataException, DatabaseException { - final CveDB cve = CveDB.getInstance(); - if (!cve.dataExists()) { + private void ensureDataExists() throws NoDataException { + if (database == null || !database.dataExists()) { throw new NoDataException("No documents exist"); } - CveDB.close(); } /** 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 b6c35acef..2ee63b1f6 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 @@ -843,15 +843,11 @@ public class DependencyCheckScanAgent { */ private void generateExternalReports(Engine engine, File outDirectory) { DatabaseProperties prop = null; - CveDB cve; - try { - cve = CveDB.getInstance(); + try (CveDB cve = CveDB.getInstance()) { prop = cve.getDatabaseProperties(); } catch (DatabaseException ex) { - //TODO shouldn't this throw an exception or return? + //TODO shouldn't this be a fatal exception LOGGER.debug("Unable to retrieve DB Properties", ex); - } finally { - CveDB.close(); } final ReportGenerator r = new ReportGenerator(this.applicationName, engine.getDependencies(), engine.getAnalyzers(), prop); try { diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java index f30127e35..14177fa9b 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java @@ -183,7 +183,7 @@ public class CPEAnalyzer extends AbstractAnalyzer { @Override public void closeAnalyzer() { if (cve != null) { - CveDB.close(); + cve.close(); cve = null; } if (cpe != null) { diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NvdCveAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NvdCveAnalyzer.java index e254932af..c3cdedf2f 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NvdCveAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NvdCveAnalyzer.java @@ -68,7 +68,7 @@ public class NvdCveAnalyzer extends AbstractAnalyzer { */ @Override public void closeAnalyzer() { - CveDB.close(); + cveDB.close(); cveDB = null; } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java index bd7b79b7c..e872dd050 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java @@ -132,7 +132,8 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { LOGGER.info("Launching: " + args + " from " + folder); return builder.start(); } catch (IOException ioe) { - throw new AnalysisException("bundle-audit failure", ioe); + throw new AnalysisException("bundle-audit initialization failure; this error can be ignored if you are not analyzing Ruby. " + + "Otherwise ensure that bundle-audit is installed and the path to bundle audit is correctly specified", ioe); } } @@ -159,7 +160,6 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { } catch (AnalysisException ae) { setEnabled(false); - cvedb = null; final String msg = String.format("Exception from bundle-audit process: %s. Disabling %s", ae.getCause(), ANALYZER_NAME); throw new InitializationException(msg, ae); } catch (IOException ex) { @@ -208,14 +208,17 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { } } - /** + /** * Closes the data source. */ @Override public void closeAnalyzer() { - CveDB.close(); - cvedb = null; + if (cvedb != null) { + cvedb.close(); + cvedb = null; + } } + /** * Returns the name of the analyzer. * diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.java index b901231b4..4402fd341 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.java @@ -241,13 +241,31 @@ public final class ConnectionFactory { * @throws IOException thrown if the data directory does not exist and * cannot be created */ - private static boolean h2DataFileExists() throws IOException { + public static boolean h2DataFileExists() throws IOException { final File dir = Settings.getDataDirectory(); final String fileName = Settings.getString(Settings.KEYS.DB_FILE_NAME); final File file = new File(dir, fileName); return file.exists(); } + /** + * Determines if the connection string is for an H2 database. + * + * @return true if the connection string is for an H2 database + */ + public static boolean isH2Connection() { + String connStr; + try { + connStr = Settings.getConnectionString( + Settings.KEYS.DB_CONNECTION_STRING, + Settings.KEYS.DB_FILE_NAME); + } catch (IOException ex) { + LOGGER.debug("Unable to get connectionn string", ex); + return false; + } + return connStr.startsWith("jdbc:h2:file:"); + } + /** * Creates the database structure (tables and indexes) to store the CVE * data. 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 ac105dbf6..bb32ae907 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 @@ -58,7 +58,7 @@ import static org.owasp.dependencycheck.data.nvdcve.CveDB.PreparedStatementCveDb * @author Jeremy Long */ @ThreadSafe -public final class CveDB { +public final class CveDB implements AutoCloseable { /** * Singleton instance of the CveDB. @@ -253,7 +253,8 @@ public final class CveDB { * Closes the database connection. Close should be called on this object * when it is done being used. */ - public static synchronized void close() { + @Override + public synchronized void close() { if (instance != null) { instance.usageCount -= 1; if (instance.usageCount <= 0 && instance.isOpen()) { @@ -281,7 +282,7 @@ public final class CveDB { * * @return whether the database connection is open or closed */ - private synchronized boolean isOpen() { + protected synchronized boolean isOpen() { return connection != null; } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/EngineVersionCheck.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/EngineVersionCheck.java index 6958d6ba7..2bd2eb5ef 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/EngineVersionCheck.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/EngineVersionCheck.java @@ -93,8 +93,7 @@ public class EngineVersionCheck implements CachedWebDataSource { */ @Override public void update() throws UpdateException { - try { - final CveDB db = CveDB.getInstance(); + try (CveDB db = CveDB.getInstance()) { final boolean autoupdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE, true); final boolean enabled = Settings.getBoolean(Settings.KEYS.UPDATE_VERSION_CHECK_ENABLED, true); final String original = Settings.getString(Settings.KEYS.CVE_ORIGINAL_MODIFIED_20_URL); @@ -127,8 +126,6 @@ public class EngineVersionCheck implements CachedWebDataSource { throw new UpdateException("Error occurred updating database properties."); } catch (InvalidSettingException ex) { LOGGER.debug("Unable to determine if autoupdate is enabled", ex); - } finally { - CveDB.close(); } } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java index 98a12d958..2ae21797c 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java @@ -104,17 +104,17 @@ public class NvdCveUpdater implements CachedWebDataSource { LOGGER.trace("invalid setting UPDATE_NVDCVE_ENABLED", ex); } + boolean autoUpdate = true; + try { + autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); + } catch (InvalidSettingException ex) { + LOGGER.debug("Invalid setting for auto-update; using true."); + } + if (!autoUpdate) { + return; + } + initializeExecutorServices(); try { - boolean autoUpdate = true; - try { - autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); - } catch (InvalidSettingException ex) { - LOGGER.debug("Invalid setting for auto-update; using true."); - } - if (!autoUpdate) { - return; - } - initializeExecutorServices(); cveDb = CveDB.getInstance(); dbProperties = cveDb.getDatabaseProperties(); @@ -139,7 +139,7 @@ public class NvdCveUpdater implements CachedWebDataSource { throw new UpdateException("Database Exception, unable to update the data to use the most current data.", ex); } finally { shutdownExecutorServices(); - CveDB.close(); + cveDb.close(); } } @@ -202,13 +202,10 @@ public class NvdCveUpdater implements CachedWebDataSource { * @return true if the database contains data */ private boolean dataExists() { - try { - final CveDB cve = CveDB.getInstance(); + try (CveDB cve = CveDB.getInstance()) { return cve.dataExists(); } catch (DatabaseException ex) { return false; - } finally { - CveDB.close(); } } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java index 0c2fd0bdf..fb0e17448 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java @@ -51,7 +51,6 @@ public abstract class BaseDBTestCase extends BaseTest { @Before public void setUpDb() throws Exception { ensureDBExists(); - CveDB.getInstance().openDatabase(); } public static void ensureDBExists() throws Exception { diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineIntegrationTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineIntegrationTest.java index 85958a39c..94f58dba6 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineIntegrationTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineIntegrationTest.java @@ -71,10 +71,11 @@ public class EngineIntegrationTest extends BaseDBTestCase { throw ex; } } - CveDB cveDB = CveDB.getInstance(); - DatabaseProperties dbProp = cveDB.getDatabaseProperties(); - CveDB.close(); - ReportGenerator rg = new ReportGenerator("DependencyCheck", instance.getDependencies(), instance.getAnalyzers(), dbProp); + 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.cleanup(); } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java index d2e655ac7..ea986dfbf 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java @@ -28,6 +28,7 @@ import java.util.List; import java.util.Set; import org.junit.After; +import static org.junit.Assert.assertNotNull; import org.junit.Assume; import org.junit.Before; import org.junit.Test; @@ -53,7 +54,7 @@ import org.owasp.dependencycheck.exception.InitializationException; * @author Dale Visser */ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { - + private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzerTest.class); /** @@ -82,8 +83,10 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { */ @After public void tearDown() throws Exception { - analyzer.close(); - analyzer = null; + if (analyzer != null) { + analyzer.close(); + analyzer = null; + } } /** @@ -117,7 +120,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { analyzer.analyze(result, engine); int size = engine.getDependencies().size(); assertTrue(size >= 1); - + Dependency dependency = engine.getDependencies().get(0); assertTrue(dependency.getProductEvidence().toString().toLowerCase().contains("redcarpet")); assertTrue(dependency.getVersionEvidence().toString().toLowerCase().contains("2.2.2")); @@ -136,16 +139,16 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { public void testAddCriticalityToVulnerability() throws AnalysisException, DatabaseException { try { analyzer.initialize(); - + final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, "ruby/vulnerable/gems/sinatra/Gemfile.lock")); final Engine engine = new Engine(); analyzer.analyze(result, engine); - + Dependency dependency = engine.getDependencies().get(0); Vulnerability vulnerability = dependency.getVulnerabilities().first(); assertEquals(vulnerability.getCvssScore(), 5.0f, 0.0); - + } catch (InitializationException | DatabaseException | AnalysisException e) { LOGGER.warn("Exception setting up RubyBundleAuditAnalyzer. Make sure Ruby gem bundle-audit is installed. You may also need to set property \"analyzer.bundle.audit.path\"."); Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e); @@ -166,7 +169,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { analyzer.initialize(); } catch (Exception e) { //expected, so ignore. - LOGGER.error("Exception", e); + assertNotNull(e); } finally { assertThat(analyzer.isEnabled(), is(false)); LOGGER.info("phantom-bundle-audit is not available. Ruby Bundle Audit Analyzer is disabled as expected."); @@ -191,6 +194,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { fail(ex.getMessage()); } catch (ExceptionCollection ex) { Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", ex); + return; } List dependencies = engine.getDependencies(); LOGGER.info(dependencies.size() + " dependencies found."); @@ -198,14 +202,14 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { while (dIterator.hasNext()) { Dependency dept = dIterator.next(); LOGGER.info("dept path: " + dept.getActualFilePath()); - + Set identifiers = dept.getIdentifiers(); Iterator idIterator = identifiers.iterator(); while (idIterator.hasNext()) { Identifier id = idIterator.next(); LOGGER.info(" Identifier: " + id.getValue() + ", type=" + id.getType() + ", url=" + id.getUrl() + ", conf=" + id.getConfidence()); } - + Set prodEv = dept.getProductEvidence().getEvidence(); Iterator it = prodEv.iterator(); while (it.hasNext()) { @@ -218,7 +222,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { Evidence e = vIt.next(); LOGGER.info(" version: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); } - + Set vendorEv = dept.getVendorEvidence().getEvidence(); Iterator vendorIt = vendorEv.iterator(); while (vendorIt.hasNext()) { diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBIntegrationTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBIntegrationTest.java index 916f9462d..32cf3a9f2 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBIntegrationTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBIntegrationTest.java @@ -29,6 +29,7 @@ import java.util.Map.Entry; import java.util.Set; import org.junit.Test; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -52,7 +53,8 @@ public class CveDBIntegrationTest extends BaseDBTestCase { } catch (DatabaseException | SQLException ex) { fail(ex.getMessage()); } finally { - CveDB.close(); + instance.close(); + assertFalse(instance.isOpen()); } } @@ -66,7 +68,7 @@ public class CveDBIntegrationTest extends BaseDBTestCase { String product = "struts"; Set result = instance.getCPEs(vendor, product); assertTrue(result.size() > 5); - CveDB.close(); + instance.close(); } /** @@ -77,7 +79,7 @@ public class CveDBIntegrationTest extends BaseDBTestCase { CveDB instance = CveDB.getInstance(); Vulnerability result = instance.getVulnerability("CVE-2014-0094"); assertEquals("The ParametersInterceptor in Apache Struts before 2.3.16.1 allows remote attackers to \"manipulate\" the ClassLoader via the class parameter, which is passed to the getClass method.", result.getDescription()); - CveDB.close(); + instance.close(); } /** @@ -114,7 +116,7 @@ public class CveDBIntegrationTest extends BaseDBTestCase { } } assertTrue("Expected " + expected + ", but was not identified", found); - CveDB.close(); + instance.close(); } /** @@ -170,6 +172,6 @@ public class CveDBIntegrationTest extends BaseDBTestCase { identifiedVersion = new DependencyVersion("1.6.3"); results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); assertNotNull(results); - CveDB.close(); + instance.close(); } } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.java index dbe7d22bc..6915ee6de 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.java @@ -19,6 +19,7 @@ package org.owasp.dependencycheck.data.nvdcve; import java.util.List; import java.util.Set; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -39,13 +40,15 @@ public class CveDBMySQLTest extends BaseTest { */ @Test public void testOpen() { + CveDB instance = null; try { - CveDB instance = CveDB.getInstance(); + instance = CveDB.getInstance(); } catch (DatabaseException ex) { System.out.println("Unable to connect to the My SQL database; verify that the db server is running and that the schema has been generated"); fail(ex.getMessage()); } finally { - CveDB.close(); + instance.close(); + assertFalse(instance.isOpen()); } } @@ -57,14 +60,14 @@ public class CveDBMySQLTest extends BaseTest { CveDB instance = CveDB.getInstance(); try { String vendor = "apache"; - String product = "struts"; + String product = "struts"; Set result = instance.getCPEs(vendor, product); assertTrue("Has data been loaded into the MySQL DB? if not consider using the CLI to populate it", result.size() > 5); } catch (Exception ex) { System.out.println("Unable to access the My SQL database; verify that the db server is running and that the schema has been generated"); throw ex; } finally { - CveDB.close(); + instance.close(); } } @@ -82,7 +85,7 @@ public class CveDBMySQLTest extends BaseTest { System.out.println("Unable to access the My SQL database; verify that the db server is running and that the schema has been generated"); throw ex; } finally { - CveDB.close(); + instance.close(); } } } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DatabasePropertiesIntegrationTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DatabasePropertiesIntegrationTest.java index 6067f8e40..2a64775ae 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DatabasePropertiesIntegrationTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DatabasePropertiesIntegrationTest.java @@ -41,7 +41,7 @@ public class DatabasePropertiesIntegrationTest extends BaseDBTestCase { assertNotNull(instance); //no exception means the call worked... whether or not it is empty depends on if the db is new //assertEquals(expResult, result); - CveDB.close(); + cveDB.close(); } /** @@ -60,7 +60,7 @@ public class DatabasePropertiesIntegrationTest extends BaseDBTestCase { instance = cveDB.reloadProperties(); long results = Long.parseLong(instance.getProperty("NVD CVE " + key)); assertEquals(expected, results); - CveDB.close(); + cveDB.close(); } /** @@ -75,7 +75,7 @@ public class DatabasePropertiesIntegrationTest extends BaseDBTestCase { String expResult = "default"; String result = instance.getProperty(key, defaultValue); assertEquals(expResult, result); - CveDB.close(); + cveDB.close(); } /** @@ -90,7 +90,7 @@ public class DatabasePropertiesIntegrationTest extends BaseDBTestCase { double version = Double.parseDouble(result); assertTrue(version >= 2.8); assertTrue(version <= 10); - CveDB.close(); + cveDB.close(); } /** @@ -102,6 +102,6 @@ public class DatabasePropertiesIntegrationTest extends BaseDBTestCase { DatabaseProperties instance = cveDB.getDatabaseProperties(); Properties result = instance.getProperties(); assertTrue(result.size() > 0); - CveDB.close(); + cveDB.close(); } } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.java index 0b9e72390..f0a7ff01c 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.java @@ -149,7 +149,7 @@ public class ReportGeneratorIntegrationTest extends BaseDBTestCase { ReportGenerator generator = new ReportGenerator("Test Report", engine.getDependencies(), engine.getAnalyzers(), dbProp); generator.generateReport(templateName, writeTo); - CveDB.close(); + cveDB.close(); engine.cleanup(); 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 629d722a4..76b74d9dd 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 @@ -1007,8 +1007,7 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma */ protected void writeReports(Engine engine, MavenProject p, File outputDir) throws ReportException { DatabaseProperties prop = null; - try { - final CveDB cve = CveDB.getInstance(); + try (CveDB cve = CveDB.getInstance()) { prop = cve.getDatabaseProperties(); } catch (DatabaseException ex) { //TODO shouldn't this throw an exception? @@ -1017,7 +1016,6 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma } } final ReportGenerator r = new ReportGenerator(p.getName(), engine.getDependencies(), engine.getAnalyzers(), prop); - CveDB.close(); try { r.generateReports(outputDir.getAbsolutePath(), format); } catch (ReportException ex) {