From 9ba44e32fb779874e45e65664c5576c93fa0dfe7 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sun, 23 Feb 2014 08:42:16 -0500 Subject: [PATCH] re-wrote the retrieval of the vendor product list to use a generic pair and completely encapsulate all sql objects in CveDB Former-commit-id: f84c88e2acc3c876228150736c71290b3467e2d2 --- .../data/cpe/CpeMemoryIndex.java | 18 ++- .../dependencycheck/data/nvdcve/CveDB.java | 23 +++- .../org/owasp/dependencycheck/utils/Pair.java | 124 ++++++++++++++++++ 3 files changed, 148 insertions(+), 17 deletions(-) create mode 100644 dependency-check-core/src/main/java/org/owasp/dependencycheck/utils/Pair.java diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/cpe/CpeMemoryIndex.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/cpe/CpeMemoryIndex.java index 93101e417..4c8851caa 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/cpe/CpeMemoryIndex.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/cpe/CpeMemoryIndex.java @@ -18,10 +18,9 @@ package org.owasp.dependencycheck.data.cpe; import java.io.IOException; -import java.sql.ResultSet; -import java.sql.SQLException; import java.util.HashMap; import java.util.Map; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.lucene.analysis.Analyzer; @@ -45,6 +44,8 @@ import org.owasp.dependencycheck.data.lucene.FieldAnalyzer; import org.owasp.dependencycheck.data.lucene.LuceneUtils; import org.owasp.dependencycheck.data.lucene.SearchFieldAnalyzer; import org.owasp.dependencycheck.data.nvdcve.CveDB; +import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +import org.owasp.dependencycheck.utils.Pair; /** * An in memory lucene index that contains the vendor/product combinations from the CPE (application) identifiers within @@ -210,7 +211,7 @@ public final class CpeMemoryIndex { } /** - * Builds the lucene index based off of the data within the CveDB. + * Builds the CPE Lucene Index based off of the data within the CveDB. * * @param cve the data base containing the CPE data * @throws IndexException thrown if there is an issue creating the index @@ -222,15 +223,12 @@ public final class CpeMemoryIndex { analyzer = createIndexingAnalyzer(); final IndexWriterConfig conf = new IndexWriterConfig(LuceneUtils.CURRENT_VERSION, analyzer); indexWriter = new IndexWriter(index, conf); - final ResultSet rs = cve.getVendorProductList(); - if (rs == null) { - throw new IndexException("No data exists"); - } try { - while (rs.next()) { - saveEntry(rs.getString(1), rs.getString(2), indexWriter); + final Set> data = cve.getVendorProductList(); + for (Pair pair : data) { + saveEntry(pair.getLeft(), pair.getRight(), indexWriter); } - } catch (SQLException ex) { + } catch (DatabaseException ex) { Logger.getLogger(CpeMemoryIndex.class.getName()).log(Level.FINE, null, ex); throw new IndexException("Error reading CPE data", ex); } 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 462c20a52..5ccbf08a9 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 @@ -38,6 +38,7 @@ import org.owasp.dependencycheck.dependency.VulnerableSoftware; import org.owasp.dependencycheck.utils.DBUtils; import org.owasp.dependencycheck.utils.DependencyVersion; import org.owasp.dependencycheck.utils.DependencyVersionUtil; +import org.owasp.dependencycheck.utils.Pair; /** * The database holding information about the NVD CVE data. @@ -295,19 +296,27 @@ public class CveDB { /** * Returns the entire list of vendor/product combinations. * - * @return the entire list of vendor/product combinations. + * @return the entire list of vendor/product combinations + * @throws DatabaseException thrown when there is an error retrieving the data from the DB */ - public ResultSet getVendorProductList() { + public Set> getVendorProductList() throws DatabaseException { + HashSet data = new HashSet>(); ResultSet rs = null; + PreparedStatement ps = null; try { - final PreparedStatement ps = getConnection().prepareStatement(SELECT_VENDOR_PRODUCT_LIST); + ps = getConnection().prepareStatement(SELECT_VENDOR_PRODUCT_LIST); rs = ps.executeQuery(); + while (rs.next()) { + data.add(new Pair(rs.getString(1), rs.getString(2))); + } } catch (SQLException ex) { final String msg = "An unexpected SQL Exception occurred; please see the verbose log for more details."; - Logger.getLogger(CveDB.class.getName()).log(Level.SEVERE, msg); - Logger.getLogger(CveDB.class.getName()).log(Level.FINE, null, ex); - } // can't close the statement in the PS as the resultset is returned, closing PS would close the resultset - return rs; + throw new DatabaseException(msg, ex); + } finally { + DBUtils.closeResultSet(rs); + DBUtils.closeStatement(ps); + } + return data; } /** diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/utils/Pair.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/utils/Pair.java new file mode 100644 index 000000000..eee908a09 --- /dev/null +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/utils/Pair.java @@ -0,0 +1,124 @@ +/* + * 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) 2014 Jeremy Long. All Rights Reserved. + */ +package org.owasp.dependencycheck.utils; + +/** + * A generic pair of elements. + * + * @author Jeremy Long + */ +public class Pair { + + /** + * Constructs a new empty pair. + */ + public Pair() { + } + + /** + * Constructs a new Pair with the given left and right values. + * + * @param left the value for the left pair + * @param right the value for the right pair + */ + public Pair(K left, V right) { + this.left = left; + this.right = right; + } + /** + * The left element of the pair. + */ + private K left = null; + + /** + * Get the value of left + * + * @return the value of left + */ + public K getLeft() { + return left; + } + + /** + * Set the value of left + * + * @param left new value of left + */ + public void setLeft(K left) { + this.left = left; + } + /** + * The right element of the pair. + */ + private V right = null; + + /** + * Get the value of right + * + * @return the value of right + */ + public V getRight() { + return right; + } + + /** + * Set the value of right + * + * @param right new value of right + */ + public void setRight(V right) { + this.right = right; + } + + /** + * Generates the hash code using the hash codes from the contained objects. + * + * @return the hash code of the Pair + */ + @Override + public int hashCode() { + int hash = 3; + hash = 53 * hash + (this.left != null ? this.left.hashCode() : 0); + hash = 53 * hash + (this.right != null ? this.right.hashCode() : 0); + return hash; + } + + /** + * Determines the equality of this and the provided object. + * + * @param obj the {@link Object} to check for equality to this + * @return true if this and the provided {@link Object} are equal; otherwise false + */ + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Pair other = (Pair) obj; + if (this.left != other.left && (this.left == null || !this.left.equals(other.left))) { + return false; + } + if (this.right != other.right && (this.right == null || !this.right.equals(other.right))) { + return false; + } + return true; + } +}