diff --git a/.gitignore b/.gitignore index 09bf20505..5369f2ed3 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ _site/** .LCKpom.xml~ #coverity /cov-int/ +/dependency-check-core/nbproject/ \ No newline at end of file diff --git a/dependency-check-ant/pom.xml b/dependency-check-ant/pom.xml index 5881e3f7b..74cd4e634 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.3.6-SNAPSHOT + 1.3.7-SNAPSHOT dependency-check-ant @@ -256,6 +256,7 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved. org.apache.maven.plugins maven-surefire-plugin + -Dfile.encoding=UTF-8 data.directory diff --git a/dependency-check-cli/pom.xml b/dependency-check-cli/pom.xml index 23e392343..33b10ec80 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.3.6-SNAPSHOT + 1.3.7-SNAPSHOT dependency-check-cli @@ -110,6 +110,7 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved. org.apache.maven.plugins maven-surefire-plugin + -Dfile.encoding=UTF-8 cpe diff --git a/dependency-check-core/pom.xml b/dependency-check-core/pom.xml index 2cc6229ab..fcf2641d0 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.3.6-SNAPSHOT + 1.3.7-SNAPSHOT dependency-check-core @@ -178,6 +178,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved. org.apache.maven.plugins maven-surefire-plugin + -Dfile.encoding=UTF-8 data.directory diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.java index a730acf7e..97c0719d5 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.java @@ -24,6 +24,7 @@ import java.net.MalformedURLException; import java.net.URL; import java.util.List; import java.util.Set; +import java.util.logging.Level; import java.util.regex.Pattern; import org.owasp.dependencycheck.suppression.SuppressionParseException; import org.owasp.dependencycheck.suppression.SuppressionParser; @@ -34,6 +35,7 @@ import org.owasp.dependencycheck.utils.FileUtils; import org.owasp.dependencycheck.utils.Settings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.xml.sax.SAXException; /** * Abstract base suppression analyzer that contains methods for parsing the suppression xml file. @@ -103,6 +105,10 @@ public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer { try { rules = parser.parseSuppressionRules(this.getClass().getClassLoader().getResourceAsStream("dependencycheck-base-suppression.xml")); } catch (SuppressionParseException ex) { + LOGGER.error("Unable to parse the base suppression data file"); + LOGGER.debug("Unable to parse the base suppression data file", ex); + } catch (SAXException ex) { + LOGGER.error("Unable to parse the base suppression data file"); LOGGER.debug("Unable to parse the base suppression data file", ex); } final String suppressionFilePath = Settings.getString(Settings.KEYS.SUPPRESSION_FILE); diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.java index 04dcfcefe..7a865ecbf 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.java @@ -30,6 +30,7 @@ import org.owasp.dependencycheck.utils.UrlStringUtils; import java.io.File; import java.io.FileFilter; import java.io.IOException; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; @@ -220,14 +221,12 @@ public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer { */ private String getFileContents(final File actualFile) throws AnalysisException { - String contents = ""; try { - contents = FileUtils.readFileToString(actualFile).trim(); + return FileUtils.readFileToString(actualFile, Charset.defaultCharset()).trim(); } catch (IOException e) { throw new AnalysisException( "Problem occurred while reading dependency file.", e); } - return contents; } /** diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.java index 55a81e216..6237f4777 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.java @@ -33,6 +33,7 @@ import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.regex.Matcher; @@ -156,7 +157,7 @@ public class CMakeAnalyzer extends AbstractFileTypeAnalyzer { dependency.setDisplayFileName(String.format("%s%c%s", parentName, File.separatorChar, name)); String contents; try { - contents = FileUtils.readFileToString(file).trim(); + contents = FileUtils.readFileToString(file, Charset.defaultCharset()).trim(); } catch (IOException e) { throw new AnalysisException( "Problem occurred while reading dependency file.", e); diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.java index cf45f6806..56e894841 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.java @@ -28,6 +28,7 @@ import org.owasp.dependencycheck.utils.Settings; import java.io.File; import java.io.FileFilter; import java.io.IOException; +import java.nio.charset.Charset; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -158,14 +159,12 @@ public class OpenSSLAnalyzer extends AbstractFileTypeAnalyzer { */ private String getFileContents(final File actualFile) throws AnalysisException { - String contents; try { - contents = FileUtils.readFileToString(actualFile).trim(); + return FileUtils.readFileToString(actualFile, Charset.defaultCharset()).trim(); } catch (IOException e) { throw new AnalysisException( "Problem occurred while reading dependency file.", e); } - return contents; } @Override diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.java index 25c689073..527892bce 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.java @@ -32,6 +32,7 @@ import org.owasp.dependencycheck.utils.UrlStringUtils; import java.io.File; import java.io.FileFilter; import java.io.IOException; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; @@ -210,7 +211,7 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer { throws AnalysisException { String contents; try { - contents = FileUtils.readFileToString(file).trim(); + contents = FileUtils.readFileToString(file, Charset.defaultCharset()).trim(); } catch (IOException e) { throw new AnalysisException( "Problem occurred while reading dependency file.", e); 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 b007d7220..d95c1a7cc 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 @@ -20,6 +20,7 @@ package org.owasp.dependencycheck.analyzer; import org.apache.commons.io.FileUtils; import org.owasp.dependencycheck.Engine; import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +import org.owasp.dependencycheck.data.nvdcve.CveDB; import org.owasp.dependencycheck.dependency.Confidence; import org.owasp.dependencycheck.dependency.Dependency; import org.owasp.dependencycheck.dependency.Reference; @@ -30,10 +31,14 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.*; +import java.nio.charset.Charset; import java.util.*; +import java.util.logging.Level; +import org.owasp.dependencycheck.data.nvdcve.DatabaseException; /** - * Used to analyze Ruby Bundler Gemspec.lock files utilizing the 3rd party bundle-audit tool. + * Used to analyze Ruby Bundler Gemspec.lock files utilizing the 3rd party + * bundle-audit tool. * * @author Dale Visser */ @@ -58,6 +63,10 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { public static final String ADVISORY = "Advisory: "; public static final String CRITICALITY = "Criticality: "; + public CveDB cvedb; + //instance.open(); + //Vulnerability result = instance.getVulnerability("CVE-2015-3225"); + /** * @return a filter that accepts files named Gemfile.lock */ @@ -83,7 +92,7 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { final ProcessBuilder builder = new ProcessBuilder(args); builder.directory(folder); try { - LOGGER.info("Launching: " + args + " from " + folder); + LOGGER.info("Launching: " + args + " from " + folder); return builder.start(); } catch (IOException ioe) { throw new AnalysisException("bundle-audit failure", ioe); @@ -91,23 +100,34 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Initialize the analyzer. In this case, extract GrokAssembly.exe to a temporary location. + * Initialize the analyzer. In this case, extract GrokAssembly.exe to a + * temporary location. * * @throws Exception if anything goes wrong */ @Override public void initializeFileTypeAnalyzer() throws Exception { - // Now, need to see if bundle-audit actually runs from this location. - Process process = null; - try { - process = launchBundleAudit(Settings.getTempDirectory()); - } - catch(AnalysisException ae) { - LOGGER.warn("Exception from bundle-audit process: {}. Disabling {}", ae.getCause(), ANALYZER_NAME); + try { + cvedb = new CveDB(); + cvedb.open(); + } catch (DatabaseException ex) { + LOGGER.warn("Exception opening the database"); + LOGGER.debug("error", ex); setEnabled(false); + throw ex; + } + // Now, need to see if bundle-audit actually runs from this location. + Process process = null; + try { + process = launchBundleAudit(Settings.getTempDirectory()); + } catch (AnalysisException ae) { + LOGGER.warn("Exception from bundle-audit process: {}. Disabling {}", ae.getCause(), ANALYZER_NAME); + setEnabled(false); + cvedb.close(); + cvedb = null; throw ae; - } - + } + int exitValue = process.waitFor(); if (0 == exitValue) { LOGGER.warn("Unexpected exit code from bundle-audit process. Disabling {}: {}", ANALYZER_NAME, exitValue); @@ -135,7 +155,7 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { } } } - + if (isEnabled()) { LOGGER.info(ANALYZER_NAME + " is enabled. It is necessary to manually run \"bundle-audit update\" " + "occasionally to keep its database up to date."); @@ -163,7 +183,8 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Returns the key used in the properties file to reference the analyzer's enabled property. + * Returns the key used in the properties file to reference the analyzer's + * enabled property. * * @return the analyzer's enabled property setting key */ @@ -173,8 +194,9 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { } /** - * If {@link #analyzeFileType(Dependency, Engine)} is called, then we have successfully initialized, and it will be necessary - * to disable {@link RubyGemspecAnalyzer}. + * If {@link #analyzeFileType(Dependency, Engine)} is called, then we have + * successfully initialized, and it will be necessary to disable + * {@link RubyGemspecAnalyzer}. */ private boolean needToDisableGemspecAnalyzer = true; @@ -205,11 +227,11 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { } BufferedReader rdr = null; try { - BufferedReader errReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8")); - while(errReader.ready()) { - String error = errReader.readLine(); - LOGGER.warn(error); - } + BufferedReader errReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8")); + while (errReader.ready()) { + String error = errReader.readLine(); + LOGGER.warn(error); + } rdr = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8")); processBundlerAuditOutput(dependency, engine, rdr); } catch (IOException ioe) { @@ -294,15 +316,23 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { private void addCriticalityToVulnerability(String parentName, Vulnerability vulnerability, String nextLine) { if (null != vulnerability) { final String criticality = nextLine.substring(CRITICALITY.length()).trim(); - if ("High".equals(criticality)) { - vulnerability.setCvssScore(8.5f); - } else if ("Medium".equals(criticality)) { - vulnerability.setCvssScore(5.5f); - } else if ("Low".equals(criticality)) { - vulnerability.setCvssScore(2.0f); - } else { - vulnerability.setCvssScore(-1.0f); + float score = -1.0f; + Vulnerability v = null; + try { + v = cvedb.getVulnerability(vulnerability.getName()); + } catch (DatabaseException ex) { + LOGGER.debug("Unable to look up vulnerability {}", vulnerability.getName()); } + if (v != null) { + score = v.getCvssScore(); + } else if ("High".equalsIgnoreCase(criticality)) { + score = 8.5f; + } else if ("Medium".equalsIgnoreCase(criticality)) { + score = 5.5f; + } else if ("Low".equalsIgnoreCase(criticality)) { + score = 2.0f; + } + vulnerability.setCvssScore(score); } LOGGER.debug(String.format("bundle-audit (%s): %s", parentName, nextLine)); } @@ -334,7 +364,8 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { final File gemFile = new File(Settings.getTempDirectory(), gem + "_Gemfile.lock"); gemFile.createNewFile(); final String displayFileName = String.format("%s%c%s:%s", parentName, File.separatorChar, fileName, gem); - FileUtils.write(gemFile, displayFileName); // unique contents to avoid dependency bundling + + FileUtils.write(gemFile, displayFileName, Charset.defaultCharset()); // unique contents to avoid dependency bundling final Dependency dependency = new Dependency(gemFile); dependency.getProductEvidence().addEvidence("bundler-audit", "Name", gem, Confidence.HIGHEST); dependency.setDisplayFileName(displayFileName); diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java index aaa93774b..7bec4c505 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java @@ -21,6 +21,7 @@ import java.io.File; import java.io.FileFilter; import java.io.FilenameFilter; import java.io.IOException; +import java.nio.charset.Charset; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -113,7 +114,7 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { throws AnalysisException { String contents; try { - contents = FileUtils.readFileToString(dependency.getActualFile()); + contents = FileUtils.readFileToString(dependency.getActualFile(), Charset.defaultCharset()); } catch (IOException e) { throw new AnalysisException( "Problem occurred while reading dependency file.", e); 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 42bceef0d..037da7564 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 @@ -372,7 +372,7 @@ public class CveDB { * @return a vulnerability object * @throws DatabaseException if an exception occurs */ - private Vulnerability getVulnerability(String cve) throws DatabaseException { + public Vulnerability getVulnerability(String cve) throws DatabaseException { PreparedStatement psV = null; PreparedStatement psR = null; PreparedStatement psS = null; diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionParser.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionParser.java index 9b863c3d0..e4956ed1b 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionParser.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionParser.java @@ -25,6 +25,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.util.List; +import java.util.logging.Level; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; @@ -47,20 +48,24 @@ public class SuppressionParser { */ private static final Logger LOGGER = LoggerFactory.getLogger(SuppressionParser.class); /** - * JAXP Schema Language. Source: http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html + * JAXP Schema Language. Source: + * http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html */ public static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; /** - * W3C XML Schema. Source: http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html + * W3C XML Schema. Source: + * http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html */ public static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema"; /** - * JAXP Schema Source. Source: http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html + * JAXP Schema Source. Source: + * http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html */ public static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource"; /** - * Parses the given xml file and returns a list of the suppression rules contained. + * Parses the given xml file and returns a list of the suppression rules + * contained. * * @param file an xml file containing suppression rules * @return a list of suppression rules @@ -74,6 +79,20 @@ public class SuppressionParser { } catch (IOException ex) { LOGGER.debug("", ex); throw new SuppressionParseException(ex); + } catch (SAXException ex) { + try { + if (fis != null) { + try { + fis.close(); + } catch (IOException ex1) { + LOGGER.debug("Unable to close stream", ex1); + } + } + fis = new FileInputStream(file); + } catch (FileNotFoundException ex1) { + throw new SuppressionParseException(ex); + } + return parseOldSuppressionRules(fis); } finally { if (fis != null) { try { @@ -86,13 +105,62 @@ public class SuppressionParser { } /** - * Parses the given xml stream and returns a list of the suppression rules contained. + * Parses the given xml stream and returns a list of the suppression rules + * contained. * * @param inputStream an InputStream containing suppression rues * @return a list of suppression rules * @throws SuppressionParseException if the xml cannot be parsed */ - public List parseSuppressionRules(InputStream inputStream) throws SuppressionParseException { + public List parseSuppressionRules(InputStream inputStream) throws SuppressionParseException, SAXException { + try { + final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream("schema/dependency-suppression.1.1.xsd"); + final SuppressionHandler handler = new SuppressionHandler(); + final SAXParserFactory factory = SAXParserFactory.newInstance(); + factory.setNamespaceAware(true); + factory.setValidating(true); + final SAXParser saxParser = factory.newSAXParser(); + saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_LANGUAGE, SuppressionParser.W3C_XML_SCHEMA); + saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_SOURCE, new InputSource(schemaStream)); + final XMLReader xmlReader = saxParser.getXMLReader(); + xmlReader.setErrorHandler(new SuppressionErrorHandler()); + xmlReader.setContentHandler(handler); + + final Reader reader = new InputStreamReader(inputStream, "UTF-8"); + final InputSource in = new InputSource(reader); + //in.setEncoding("UTF-8"); + + xmlReader.parse(in); + + return handler.getSuppressionRules(); + } catch (ParserConfigurationException ex) { + LOGGER.debug("", ex); + throw new SuppressionParseException(ex); + } catch (SAXException ex) { + if (ex.getMessage().contains("Cannot find the declaration of element 'suppressions'.")) { + throw ex; + } else { + LOGGER.debug("", ex); + throw new SuppressionParseException(ex); + } + } catch (FileNotFoundException ex) { + LOGGER.debug("", ex); + throw new SuppressionParseException(ex); + } catch (IOException ex) { + LOGGER.debug("", ex); + throw new SuppressionParseException(ex); + } + } + + /** + * Parses the given xml stream and returns a list of the suppression rules + * contained. + * + * @param inputStream an InputStream containing suppression rues + * @return a list of suppression rules + * @throws SuppressionParseException if the xml cannot be parsed + */ + private List parseOldSuppressionRules(InputStream inputStream) throws SuppressionParseException { try { final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream("schema/suppression.xsd"); final SuppressionHandler handler = new SuppressionHandler(); diff --git a/dependency-check-core/src/main/resources/data/initialize_mssql.sql b/dependency-check-core/src/main/resources/data/initialize_mssql.sql new file mode 100644 index 000000000..bdba850fc --- /dev/null +++ b/dependency-check-core/src/main/resources/data/initialize_mssql.sql @@ -0,0 +1,36 @@ +if exists (SELECT 1 FROM sysobjects WHERE name='software' AND xtype='U') + drop table software +if exists (SELECT 1 FROM sysobjects WHERE name='cpeEntry' AND xtype='U') + drop table cpeEntry +if exists (SELECT 1 FROM sysobjects WHERE name='reference' AND xtype='U') + drop table reference +if exists (SELECT 1 FROM sysobjects WHERE name='vulnerability' AND xtype='U') + drop table vulnerability +if exists (SELECT 1 FROM sysobjects WHERE name='properties' AND xtype='U') + drop table properties + +CREATE TABLE properties (id varchar(50) PRIMARY KEY, value varchar(500)); + +CREATE TABLE vulnerability (id int identity(1,1) PRIMARY KEY, cve VARCHAR(20) UNIQUE, + description VARCHAR(8000), cwe VARCHAR(10), cvssScore DECIMAL(3,1), cvssAccessVector VARCHAR(20), + cvssAccessComplexity VARCHAR(20), cvssAuthentication VARCHAR(20), cvssConfidentialityImpact VARCHAR(20), + cvssIntegrityImpact VARCHAR(20), cvssAvailabilityImpact VARCHAR(20)); + +CREATE TABLE reference (cveid INT, name VARCHAR(1000), url VARCHAR(1000), source VARCHAR(255), + CONSTRAINT FK_Reference FOREIGN KEY (cveid) REFERENCES vulnerability(id) ON DELETE CASCADE); + +CREATE TABLE cpeEntry (id INT identity(1,1) PRIMARY KEY, cpe VARCHAR(250), vendor VARCHAR(255), product VARCHAR(255)); + +CREATE TABLE software (cveid INT, cpeEntryId INT, previousVersion VARCHAR(50) + , CONSTRAINT FK_SoftwareCve FOREIGN KEY (cveid) REFERENCES vulnerability(id) ON DELETE CASCADE + , CONSTRAINT FK_SoftwareCpeProduct FOREIGN KEY (cpeEntryId) REFERENCES cpeEntry(id) + , PRIMARY KEY (cveid, cpeEntryId)); + +CREATE INDEX idxVulnerability ON vulnerability(cve); +CREATE INDEX idxReference ON reference(cveid); +CREATE INDEX idxCpe ON cpeEntry(cpe); +CREATE INDEX idxCpeEntry ON cpeEntry(vendor, product); +CREATE INDEX idxSoftwareCve ON software(cveid); +CREATE INDEX idxSoftwareCpe ON software(cpeEntryId); + +INSERT INTO properties(id,value) VALUES ('version','3.0'); \ No newline at end of file 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 81a01a185..4bec87b70 100644 --- a/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml +++ b/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml @@ -1,5 +1,5 @@ - + io\.dropwizard\.metrics:metrics-httpclient:.* cpe:/a:apache:httpclient + + + javax\.transaction:javax\.transaction-api:.* + cpe:/a:oracle:glassfish + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dependency-check-core/src/main/resources/schema/suppression.xsd b/dependency-check-core/src/main/resources/schema/suppression.xsd index bb1959e1e..5a5b483ab 100644 --- a/dependency-check-core/src/main/resources/schema/suppression.xsd +++ b/dependency-check-core/src/main/resources/schema/suppression.xsd @@ -56,4 +56,4 @@ - + \ No newline at end of file diff --git a/dependency-check-core/src/main/resources/templates/HtmlReport.vsl b/dependency-check-core/src/main/resources/templates/HtmlReport.vsl index b5098d566..a1b9b22ea 100644 --- a/dependency-check-core/src/main/resources/templates/HtmlReport.vsl +++ b/dependency-check-core/src/main/resources/templates/HtmlReport.vsl @@ -79,7 +79,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved. setTimeout('$("#modal-content,#modal-background").toggleClass("active");',100); }); $('#modal-add-header').click(function () { - xml = '\n\n '; + xml = '\n\n '; xml += $("#modal-text").text().replace(/\n/g,'\n '); xml += '\n'; $('#modal-text').text(xml).focus().select(); 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 399b00703..511c9618e 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 @@ -31,8 +31,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * An abstract database test case that is used to ensure the H2 DB exists prior to performing tests that utilize the data - * contained within. + * An abstract database test case that is used to ensure the H2 DB exists prior + * to performing tests that utilize the data contained within. * * @author Jeremy Long */ @@ -49,6 +49,11 @@ public abstract class BaseDBTestCase extends BaseTest { public static void ensureDBExists() throws Exception { + File f = new File("./target/data/dc.h2.db"); + if (f.exists() && f.isFile() && f.length() < 71680) { + f.delete(); + } + java.io.File dataPath = Settings.getDataDirectory(); String fileName = Settings.getString(Settings.KEYS.DB_FILE_NAME); LOGGER.trace("DB file name {}", fileName); diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseTest.java index 1b6a7b4cb..b18b876cb 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseTest.java @@ -39,7 +39,7 @@ public class BaseTest { if (f.exists() && f.isFile() && f.length() < 71680) { System.err.println("------------------------------------------------"); System.err.println("------------------------------------------------"); - System.err.println("I broke the build"); + System.err.println("Test referenced CveDB() and does not extend BaseDbTestCases?"); System.err.println("------------------------------------------------"); System.err.println("------------------------------------------------"); } 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 e3fd59c9e..4c2767364 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 @@ -30,16 +30,7 @@ import org.owasp.dependencycheck.utils.Settings; * * @author Jeremy Long */ -public class EngineIntegrationTest extends BaseTest { - - @Before - public void setUp() throws Exception { - org.owasp.dependencycheck.BaseDBTestCase.ensureDBExists(); - } - - @After - public void tearDown() { - } +public class EngineIntegrationTest extends BaseDBTestCase { /** * Test running the entire engine. diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.java index 19862f09b..27527b2c2 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.java @@ -77,8 +77,8 @@ public class AbstractSuppressionAnalyzerTest extends BaseTest { Settings.setString(Settings.KEYS.SUPPRESSION_FILE, "suppressions.xml"); instance.initialize(); int expCount = 5; - List result = instance.getRules(); - assertTrue(expCount <= result.size()); + int currentSize = instance.getRules().size(); + assertTrue(expCount <= currentSize); } @Test(expected = SuppressionParseException.class) diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.java index 6f021bfc6..befa0692c 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.java @@ -20,13 +20,13 @@ package org.owasp.dependencycheck.analyzer; import java.util.Iterator; import static org.junit.Assert.assertTrue; import org.junit.Test; -import org.owasp.dependencycheck.BaseTest; +import org.owasp.dependencycheck.BaseDBTestCase; /** * * @author Jeremy Long */ -public class AnalyzerServiceTest extends BaseTest { +public class AnalyzerServiceTest extends BaseDBTestCase { /** * Test of getAnalyzers method, of class AnalyzerService. diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzerTest.java index f7549f47f..179deb433 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzerTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzerTest.java @@ -55,6 +55,7 @@ public class ComposerLockAnalyzerTest extends BaseDBTestCase { */ @Before public void setUp() throws Exception { + super.setUp(); analyzer = new ComposerLockAnalyzer(); analyzer.setFilesMatched(true); analyzer.initialize(); diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/FalsePositiveAnalyzerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/FalsePositiveAnalyzerTest.java index 37094afcc..d1b068da8 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/FalsePositiveAnalyzerTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/FalsePositiveAnalyzerTest.java @@ -18,6 +18,7 @@ package org.owasp.dependencycheck.analyzer; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.junit.Test; +import org.owasp.dependencycheck.BaseTest; import org.owasp.dependencycheck.Engine; import org.owasp.dependencycheck.dependency.Dependency; @@ -25,7 +26,7 @@ import org.owasp.dependencycheck.dependency.Dependency; * * @author Jeremy Long */ -public class FalsePositiveAnalyzerTest { +public class FalsePositiveAnalyzerTest extends BaseTest { /** * Test of getName method, of class FalsePositiveAnalyzer. diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/FileNameAnalyzerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/FileNameAnalyzerTest.java index 063f99fe7..c8b436ee5 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/FileNameAnalyzerTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/FileNameAnalyzerTest.java @@ -28,7 +28,7 @@ import org.owasp.dependencycheck.dependency.Dependency; * * @author Jeremy Long */ -public class FileNameAnalyzerTest { +public class FileNameAnalyzerTest extends BaseTest { /** * Test of getName method, of class FileNameAnalyzer. 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 0b3050e6c..70dd14d4c 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 @@ -18,6 +18,7 @@ package org.owasp.dependencycheck.analyzer; import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; @@ -37,6 +38,7 @@ import org.owasp.dependencycheck.data.nvdcve.DatabaseException; import org.owasp.dependencycheck.dependency.Dependency; import org.owasp.dependencycheck.dependency.Evidence; import org.owasp.dependencycheck.dependency.Identifier; +import org.owasp.dependencycheck.dependency.Vulnerability; import org.owasp.dependencycheck.utils.Settings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -109,6 +111,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseTest { final Engine engine = new Engine(); analyzer.analyze(result, engine); int size = engine.getDependencies().size(); + assertTrue(size >= 1); Dependency dependency = engine.getDependencies().get(0); @@ -116,13 +119,37 @@ public class RubyBundleAuditAnalyzerTest extends BaseTest { assertTrue(dependency.getVersionEvidence().toString().toLowerCase().contains("2.2.2")); assertTrue(dependency.getFilePath().endsWith(resource)); assertTrue(dependency.getFileName().equals("Gemfile.lock")); - } catch (Exception 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\".", e); Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e); } } + /** + * Test Ruby addCriticalityToVulnerability + */ + @Test + 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 (Exception 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\".", e); + Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e); + } + } + + /** * Test when Ruby bundle-audit is not available on the system. * diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/composer/ComposerLockParserTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/composer/ComposerLockParserTest.java index 444788659..b325decf0 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/composer/ComposerLockParserTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/composer/ComposerLockParserTest.java @@ -25,11 +25,12 @@ import java.io.InputStream; import java.nio.charset.Charset; import static org.junit.Assert.*; +import org.owasp.dependencycheck.BaseTest; /** * Created by colezlaw on 9/5/15. */ -public class ComposerLockParserTest { +public class ComposerLockParserTest extends BaseTest { private InputStream inputStream; diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/cpe/IndexEntryTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/cpe/IndexEntryTest.java index aa938b73c..68fd1fe99 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/cpe/IndexEntryTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/cpe/IndexEntryTest.java @@ -19,12 +19,13 @@ package org.owasp.dependencycheck.data.cpe; import org.junit.Assert; import org.junit.Test; +import org.owasp.dependencycheck.BaseTest; /** * * @author Jeremy Long */ -public class IndexEntryTest { +public class IndexEntryTest extends BaseTest { /** * Test of setName method, of class IndexEntry. diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/cwe/CweDBTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/cwe/CweDBTest.java index 63f7d509d..e6df37477 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/cwe/CweDBTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/cwe/CweDBTest.java @@ -23,31 +23,13 @@ import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.owasp.dependencycheck.BaseTest; /** * * @author Jeremy Long */ -public class CweDBTest { - - public CweDBTest() { - } - - @BeforeClass - public static void setUpClass() throws Exception { - } - - @AfterClass - public static void tearDownClass() throws Exception { - } - - @Before - public void setUp() { - } - - @After - public void tearDown() { - } +public class CweDBTest extends BaseTest { /** * Method to serialize the CWE HashMap. This is not used in production; this is only used once during dev to create diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/lucene/FieldAnalyzerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/lucene/FieldAnalyzerTest.java index fe6113768..5cffc96e4 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/lucene/FieldAnalyzerTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/lucene/FieldAnalyzerTest.java @@ -43,28 +43,13 @@ import static org.junit.Assert.assertFalse; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.owasp.dependencycheck.BaseTest; /** * * @author Jeremy Long */ -public class FieldAnalyzerTest { - - @BeforeClass - public static void setUpClass() throws Exception { - } - - @AfterClass - public static void tearDownClass() throws Exception { - } - - @Before - public void setUp() { - } - - @After - public void tearDown() { - } +public class FieldAnalyzerTest extends BaseTest { @Test public void testAnalyzers() throws Exception { diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/lucene/LuceneUtilsTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/lucene/LuceneUtilsTest.java index 7d7552bc7..418962266 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/lucene/LuceneUtilsTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/lucene/LuceneUtilsTest.java @@ -23,28 +23,13 @@ import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.owasp.dependencycheck.BaseTest; /** * * @author Jeremy Long */ -public class LuceneUtilsTest { - - @BeforeClass - public static void setUpClass() throws Exception { - } - - @AfterClass - public static void tearDownClass() throws Exception { - } - - @Before - public void setUp() { - } - - @After - public void tearDown() { - } +public class LuceneUtilsTest extends BaseTest { /** * Test of appendEscapedLuceneQuery method, of class LuceneUtils. diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/lucene/TokenPairConcatenatingFilterTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/lucene/TokenPairConcatenatingFilterTest.java index dca6675ab..e6544153a 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/lucene/TokenPairConcatenatingFilterTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/lucene/TokenPairConcatenatingFilterTest.java @@ -39,14 +39,6 @@ import org.junit.Test; */ public class TokenPairConcatenatingFilterTest extends BaseTokenStreamTestCase { - @BeforeClass - public static void setUpClass() { - } - - @AfterClass - public static void tearDownClass() { - } - @Override @Before public void setUp() throws Exception { 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 319136850..7cc99f67a 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 @@ -24,6 +24,8 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.junit.Assert; + +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.junit.Test; import org.owasp.dependencycheck.dependency.Vulnerability; @@ -73,6 +75,25 @@ public class CveDBIntegrationTest extends BaseDBTestCase { } } + /** + * Test of getVulnerability method, of class CveDB. + */ + @Test + public void testgetVulnerability() throws Exception { + CveDB instance = null; + try { + instance = new CveDB(); + instance.open(); + 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()); + + } finally { + if (instance != null) { + instance.close(); + } + } + } + /** * Test of getVulnerabilities method, of class CveDB. */ 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 ba1fcba0d..00dc3612a 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 @@ -25,6 +25,7 @@ import static org.junit.Assert.assertTrue; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.owasp.dependencycheck.BaseTest; import org.owasp.dependencycheck.dependency.Vulnerability; import org.owasp.dependencycheck.dependency.VulnerableSoftware; import org.owasp.dependencycheck.utils.Settings; @@ -33,25 +34,7 @@ import org.owasp.dependencycheck.utils.Settings; * * @author Jeremy Long */ -public class CveDBMySQLTest { - - @BeforeClass - public static void setUpClass() { - Settings.initialize(); - } - - @AfterClass - public static void tearDownClass() { - Settings.cleanup(); - } - - @Before - public void setUp() throws Exception { - } - - @After - public void tearDown() throws Exception { - } +public class CveDBMySQLTest extends BaseTest { /** * Pretty useless tests of open, commit, and close methods, of class CveDB. diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DriverLoaderTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DriverLoaderTest.java index d8dfd64ec..83885f2b2 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DriverLoaderTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DriverLoaderTest.java @@ -33,26 +33,7 @@ import org.owasp.dependencycheck.BaseTest; * * @author Jeremy Long */ -public class DriverLoaderTest { - - public DriverLoaderTest() { - } - - @BeforeClass - public static void setUpClass() { - } - - @AfterClass - public static void tearDownClass() { - } - - @Before - public void setUp() { - } - - @After - public void tearDown() { - } +public class DriverLoaderTest extends BaseTest { /** * Test of load method, of class DriverLoader. @@ -71,7 +52,8 @@ public class DriverLoaderTest { } /** - * Test of load method, of class DriverLoader; expecting an exception due to a bad driver class name. + * Test of load method, of class DriverLoader; expecting an exception due to + * a bad driver class name. */ @Test(expected = DriverLoadException.class) public void testLoad_String_ex() throws Exception { diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/update/nvd/NvdCve_1_2_HandlerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/update/nvd/NvdCve_1_2_HandlerTest.java index fa00e849f..cc6c788d7 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/update/nvd/NvdCve_1_2_HandlerTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/update/nvd/NvdCve_1_2_HandlerTest.java @@ -36,26 +36,7 @@ import org.owasp.dependencycheck.dependency.VulnerableSoftware; * * @author Jeremy Long */ -public class NvdCve_1_2_HandlerTest { - - public NvdCve_1_2_HandlerTest() { - } - - @BeforeClass - public static void setUpClass() throws Exception { - } - - @AfterClass - public static void tearDownClass() throws Exception { - } - - @Before - public void setUp() { - } - - @After - public void tearDown() { - } +public class NvdCve_1_2_HandlerTest extends BaseTest { @Test public void testParse() throws Exception { diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.java index ea1c147ad..70257e6ed 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.java @@ -33,26 +33,7 @@ import org.owasp.dependencycheck.BaseTest; * * @author Jeremy Long */ -public class NvdCve_2_0_HandlerTest { - - public NvdCve_2_0_HandlerTest() { - } - - @BeforeClass - public static void setUpClass() throws Exception { - } - - @AfterClass - public static void tearDownClass() throws Exception { - } - - @Before - public void setUp() { - } - - @After - public void tearDown() { - } +public class NvdCve_2_0_HandlerTest extends BaseTest { @Test public void testParse() { diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/DependencyTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/DependencyTest.java index cbccb2083..63733fc59 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/DependencyTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/DependencyTest.java @@ -35,26 +35,7 @@ import org.owasp.dependencycheck.data.nexus.MavenArtifact; * * @author Jeremy Long */ -public class DependencyTest { - - public DependencyTest() { - } - - @BeforeClass - public static void setUpClass() throws Exception { - } - - @AfterClass - public static void tearDownClass() throws Exception { - } - - @Before - public void setUp() { - } - - @After - public void tearDown() { - } +public class DependencyTest extends BaseTest { /** * Test of getFileName method, of class Dependency. diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/EvidenceTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/EvidenceTest.java index 56b7e6393..09953bd19 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/EvidenceTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/EvidenceTest.java @@ -20,12 +20,13 @@ package org.owasp.dependencycheck.dependency; import org.junit.Test; import static org.junit.Assert.*; import static org.hamcrest.CoreMatchers.*; +import org.owasp.dependencycheck.BaseTest; /** * * @author Jeremy Long */ -public class EvidenceTest { +public class EvidenceTest extends BaseTest { /** * Test of equals method, of class Evidence. diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.java index dce5b9883..5fa12af18 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/dependency/VulnerableSoftwareTest.java @@ -23,31 +23,13 @@ import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.owasp.dependencycheck.BaseTest; /** * * @author Jeremy Long */ -public class VulnerableSoftwareTest { - - public VulnerableSoftwareTest() { - } - - @BeforeClass - public static void setUpClass() throws Exception { - } - - @AfterClass - public static void tearDownClass() throws Exception { - } - - @Before - public void setUp() { - } - - @After - public void tearDown() { - } +public class VulnerableSoftwareTest extends BaseTest { /** * Test of equals method, of class VulnerableSoftware. 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 6f5230ced..5d5d6d47f 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 @@ -26,6 +26,7 @@ import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; import org.junit.Before; 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; @@ -36,12 +37,7 @@ import org.owasp.dependencycheck.utils.Settings; * * @author Jeremy Long */ -public class ReportGeneratorIntegrationTest extends BaseTest { - - @Before - public void setUp() throws Exception { - org.owasp.dependencycheck.BaseDBTestCase.ensureDBExists(); - } +public class ReportGeneratorIntegrationTest extends BaseDBTestCase { /** * Test of generateReport method, of class ReportGenerator. diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/PropertyTypeTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/PropertyTypeTest.java index d779ea112..47fa13d82 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/PropertyTypeTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/PropertyTypeTest.java @@ -25,31 +25,13 @@ import static org.junit.Assert.assertTrue; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.owasp.dependencycheck.BaseTest; /** * * @author Jeremy Long */ -public class PropertyTypeTest { - - public PropertyTypeTest() { - } - - @BeforeClass - public static void setUpClass() { - } - - @AfterClass - public static void tearDownClass() { - } - - @Before - public void setUp() { - } - - @After - public void tearDown() { - } +public class PropertyTypeTest extends BaseTest { /** * Test of set and getValue method, of class PropertyType. diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/SuppressionHandlerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/SuppressionHandlerTest.java index 72cde170b..651c4c0f6 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/SuppressionHandlerTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/SuppressionHandlerTest.java @@ -39,26 +39,7 @@ import org.xml.sax.XMLReader; * * @author Jeremy Long */ -public class SuppressionHandlerTest { - - public SuppressionHandlerTest() { - } - - @BeforeClass - public static void setUpClass() { - } - - @AfterClass - public static void tearDownClass() { - } - - @Before - public void setUp() { - } - - @After - public void tearDown() { - } +public class SuppressionHandlerTest extends BaseTest { /** * Test of getSuppressionRules method, of class SuppressionHandler. diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/SuppressionParserTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/SuppressionParserTest.java index dc0563e96..22cafd4b6 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/SuppressionParserTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/SuppressionParserTest.java @@ -32,26 +32,7 @@ import org.owasp.dependencycheck.BaseTest; * * @author Jeremy Long */ -public class SuppressionParserTest { - - public SuppressionParserTest() { - } - - @BeforeClass - public static void setUpClass() { - } - - @AfterClass - public static void tearDownClass() { - } - - @Before - public void setUp() { - } - - @After - public void tearDown() { - } +public class SuppressionParserTest extends BaseTest { /** * Test of parseSuppressionRules method, of class SuppressionParser. diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/SuppressionRuleTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/SuppressionRuleTest.java index cdc5c538a..0a73d13a1 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/SuppressionRuleTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/SuppressionRuleTest.java @@ -34,7 +34,7 @@ import org.owasp.dependencycheck.dependency.Vulnerability; * * @author Jeremy Long */ -public class SuppressionRuleTest { +public class SuppressionRuleTest extends BaseTest { // /** diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/utils/DateUtilTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/utils/DateUtilTest.java index fb8709932..ef97e51e8 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/utils/DateUtilTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/utils/DateUtilTest.java @@ -22,31 +22,13 @@ import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.owasp.dependencycheck.BaseTest; /** * * @author Jeremy Long */ -public class DateUtilTest { - - public DateUtilTest() { - } - - @BeforeClass - public static void setUpClass() { - } - - @AfterClass - public static void tearDownClass() { - } - - @Before - public void setUp() { - } - - @After - public void tearDown() { - } +public class DateUtilTest extends BaseTest { /** * Test of withinDateRange method, of class DateUtil. diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/utils/DependencyVersionTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/utils/DependencyVersionTest.java index fae60cbc7..a53142f89 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/utils/DependencyVersionTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/utils/DependencyVersionTest.java @@ -24,12 +24,13 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.junit.Test; +import org.owasp.dependencycheck.BaseTest; /** * * @author Jeremy Long */ -public class DependencyVersionTest { +public class DependencyVersionTest extends BaseTest { /** * Test of parseVersion method, of class DependencyVersion. diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/utils/DependencyVersionUtilTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/utils/DependencyVersionUtilTest.java index b8b49c453..6f70e3d49 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/utils/DependencyVersionUtilTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/utils/DependencyVersionUtilTest.java @@ -24,31 +24,13 @@ import static org.junit.Assert.assertNull; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import org.owasp.dependencycheck.BaseTest; /** * * @author Jeremy Long */ -public class DependencyVersionUtilTest { - - public DependencyVersionUtilTest() { - } - - @BeforeClass - public static void setUpClass() throws Exception { - } - - @AfterClass - public static void tearDownClass() throws Exception { - } - - @Before - public void setUp() { - } - - @After - public void tearDown() { - } +public class DependencyVersionUtilTest extends BaseTest { /** * Test of parseVersion method, of class DependencyVersionUtil. diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/utils/FilterTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/utils/FilterTest.java index 03a851590..dc0290d85 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/utils/FilterTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/utils/FilterTest.java @@ -23,12 +23,13 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import org.junit.Test; +import org.owasp.dependencycheck.BaseTest; /** * * @author Jeremy Long */ -public class FilterTest { +public class FilterTest extends BaseTest { /** * Test of passes method, of class Filter. diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/pom/ModelTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/pom/ModelTest.java index d99ed4712..cb6b1be5d 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/pom/ModelTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/pom/ModelTest.java @@ -23,12 +23,13 @@ import java.util.Properties; import org.junit.Test; import static org.junit.Assert.*; +import org.owasp.dependencycheck.BaseTest; /** * * @author jeremy */ -public class ModelTest { +public class ModelTest extends BaseTest { /** * Test of getName method, of class Model. 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 67f047712..adedf1b35 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 @@ -27,7 +27,7 @@ import org.owasp.dependencycheck.BaseTest; * * @author jeremy */ -public class PomUtilsTest { +public class PomUtilsTest extends BaseTest { /** * Test of readPom method, of class PomUtils. diff --git a/dependency-check-core/src/test/resources/commons-fileupload-1.2.1.suppression.xml b/dependency-check-core/src/test/resources/commons-fileupload-1.2.1.suppression.xml index 84e93daff..69939ced4 100644 --- a/dependency-check-core/src/test/resources/commons-fileupload-1.2.1.suppression.xml +++ b/dependency-check-core/src/test/resources/commons-fileupload-1.2.1.suppression.xml @@ -1,5 +1,5 @@ - + 1.4) + rack-protection (~> 1.4) + tilt (~> 1.3, >= 1.3.4) + tilt (1.4.1) + +PLATFORMS + ruby + +DEPENDENCIES + sinatra diff --git a/dependency-check-maven/pom.xml b/dependency-check-maven/pom.xml index 8fcc5b54b..65286b6aa 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.3.6-SNAPSHOT + 1.3.7-SNAPSHOT dependency-check-maven @@ -87,6 +87,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved. org.apache.maven.plugins maven-surefire-plugin + -Dfile.encoding=UTF-8 data.directory 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 925764a12..57e8677be 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 @@ -1072,7 +1072,9 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma "org.owasp.dependencycheck.dependency.VulnerabilityComparator", "org.owasp.dependencycheck.dependency.VulnerableSoftware", "org.owasp.dependencycheck.data.cpe.IndexEntry"); - ret = (List) ois.readObject(); + @SuppressWarnings("unchecked") + final List depList = (List) ois.readObject(); + ret = depList; } catch (FileNotFoundException ex) { //TODO fix logging getLog().error("", ex); diff --git a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/slf4j/MavenLoggerAdapter.java b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/slf4j/MavenLoggerAdapter.java index f1ab7b953..c568f5e72 100644 --- a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/slf4j/MavenLoggerAdapter.java +++ b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/slf4j/MavenLoggerAdapter.java @@ -27,6 +27,10 @@ import org.slf4j.helpers.MessageFormatter; * @author colezlaw */ public class MavenLoggerAdapter extends MarkerIgnoringBase { + /** + * The serial version UID for serialization. + */ + private static final long serialVersionUID = 1L; /** * A reference to the Maven log. diff --git a/dependency-check-utils/pom.xml b/dependency-check-utils/pom.xml index 5fa60d261..dbf44cd64 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.3.6-SNAPSHOT + 1.3.7-SNAPSHOT dependency-check-utils @@ -77,6 +77,7 @@ Copyright (c) 2014 - Jeremy Long. All Rights Reserved. org.apache.maven.plugins maven-surefire-plugin + -Dfile.encoding=UTF-8 data.directory diff --git a/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/Settings.java b/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/Settings.java index 270696b0a..8f1f38147 100644 --- a/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/Settings.java +++ b/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/Settings.java @@ -743,7 +743,9 @@ public final class Settings { try { value = Integer.parseInt(Settings.getString(key)); } catch (NumberFormatException ex) { - LOGGER.trace("Could not convert property '{}' to an int.", key, ex); + if (!Settings.getString(key, "").isEmpty()) { + LOGGER.debug("Could not convert property '{}={}' to an int; using {} instead.", key, Settings.getString(key), defaultValue); + } value = defaultValue; } return value; diff --git a/dependency-check-utils/src/test/java/org/owasp/dependencycheck/utils/SettingsTest.java b/dependency-check-utils/src/test/java/org/owasp/dependencycheck/utils/SettingsTest.java index 03a545816..5d0c96f93 100644 --- a/dependency-check-utils/src/test/java/org/owasp/dependencycheck/utils/SettingsTest.java +++ b/dependency-check-utils/src/test/java/org/owasp/dependencycheck/utils/SettingsTest.java @@ -139,6 +139,18 @@ public class SettingsTest extends BaseTest { Assert.assertEquals(expResult, result); } + /** + * Test of getInt method, of class Settings. + */ + @Test + public void testGetIntDefault() throws InvalidSettingException { + String key = "SomeKey"; + int expResult = 85; + Settings.setString(key, "blue"); + int result = Settings.getInt(key, expResult); + Assert.assertEquals(expResult, result); + } + /** * Test of getLong method, of class Settings. */ diff --git a/pom.xml b/pom.xml index 6644d298b..85905fcaf 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ Copyright (c) 2012 - Jeremy Long org.owasp dependency-check-parent - 1.3.6-SNAPSHOT + 1.3.7-SNAPSHOT pom @@ -125,8 +125,10 @@ Copyright (c) 2012 - Jeremy Long 4.7.2 - 1.7.20 + 1.7.21 1.1.7 + + 3.3.9 2.17 2.7 3.6 @@ -225,7 +227,7 @@ Copyright (c) 2012 - Jeremy Long org.apache.maven.plugins maven-site-plugin - 3.5 + 3.5.1 org.apache.maven.plugins @@ -335,7 +337,7 @@ Copyright (c) 2012 - Jeremy Long org.apache.maven.doxia doxia-module-markdown - 1.7 + 1.7.1 @@ -357,6 +359,7 @@ Copyright (c) 2012 - Jeremy Long + @@ -557,7 +560,7 @@ Copyright (c) 2012 - Jeremy Long commons-io commons-io - 2.4 + 2.5 org.apache.commons @@ -589,17 +592,17 @@ Copyright (c) 2012 - Jeremy Long org.apache.commons commons-compress - 1.10 + 1.11 org.apache.ant ant - 1.9.6 + 1.9.7 org.apache.ant ant-testutil - 1.9.6 + 1.9.7 org.apache.lucene @@ -624,17 +627,17 @@ Copyright (c) 2012 - Jeremy Long org.apache.maven maven-core - 3.3.3 + ${maven.api.version} org.apache.maven maven-plugin-api - 3.3.3 + ${maven.api.version} org.apache.maven maven-settings - 3.3.3 + ${maven.api.version} org.apache.maven.plugin-testing @@ -651,6 +654,7 @@ Copyright (c) 2012 - Jeremy Long maven-reporting-api 3.0 + commons-collections commons-collections @@ -686,7 +690,7 @@ Copyright (c) 2012 - Jeremy Long org.jsoup jsoup - 1.8.3 + 1.9.1 org.slf4j diff --git a/src/site/markdown/general/suppression.md b/src/site/markdown/general/suppression.md index b7c7f6d0b..ed4c5bf08 100644 --- a/src/site/markdown/general/suppression.md +++ b/src/site/markdown/general/suppression.md @@ -6,7 +6,7 @@ A sample suppression file would look like: ```xml - + - +